diff --git a/.gitignore b/.gitignore index 884d819f1..2a7e69496 100644 --- a/.gitignore +++ b/.gitignore @@ -53,7 +53,6 @@ conftest.c depcomp elisp-comp guile-*.tar.gz -guile-tools install-sh libtool ltconfig @@ -70,10 +69,48 @@ guile-readline/guile-readline-config.h guile-readline/guile-readline-config.h.in *.go TAGS -guile-1.8.pc +/meta/guile-2.0.pc +/meta/guile-2.0-uninstalled.pc gdb-pre-inst-guile -libguile/stack-limit-calibration.scm cscope.out cscope.files *.log INSTALL +*.aux +*.cp +*.cps +*.dvi +*.fn +*.fns +*.ky +*.pg +*.toc +*.tp +*.vr +*.tps +*.vrs +*.pgs +*.rn +*.rns +/meta/gdb-uninstalled-guile +/meta/guile +/meta/uninstalled-env +/examples/box-module/box +/examples/box/box +/lib/alloca.h +/lib/charset.alias +/lib/configmake.h +/lib/ref-add.sed +/lib/ref-del.sed +/lib/stdlib.h +/lib/string.h +/lib/strings.h +/lib/sys/file.h +/lib/time.h +/lib/unistd.h +/lib/unistr/.dirstamp +/GPATH +/GRTAGS +/GSYMS +/GTAGS +/meta/guile-tools diff --git a/ANNOUNCE b/ANNOUNCE index 89d8cbde4..bfbda7316 100644 --- a/ANNOUNCE +++ b/ANNOUNCE @@ -30,7 +30,7 @@ The NEWS file is quite long. Here are the most interesting entries: from threads that have not been created by Guile. * Mutexes and condition variables are now always fair. A recursive - mutex must be requested explicitely. + mutex must be requested explicitly. * The low-level thread API has been removed. diff --git a/COPYING b/COPYING new file mode 100644 index 000000000..94a9ed024 --- /dev/null +++ b/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + 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. + + + Copyright (C) + + 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 . + +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: + + Copyright (C) + 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 +. + + 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 +. diff --git a/COPYING.LESSER b/COPYING.LESSER index 8add30ad5..cca7fc278 100644 --- a/COPYING.LESSER +++ b/COPYING.LESSER @@ -1,504 +1,165 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - Preamble + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. + 0. Additional Definitions. - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. + 1. Exception to Section 3 of the GNU GPL. - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. + 2. Conveying Modified Versions. - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + 3. Object Code Incorporating Material from Library Header Files. - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) + b) Accompany the object code with a copy of the GNU GPL and this license + document. - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. + 4. Combined Works. - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! - - diff --git a/FAQ b/FAQ deleted file mode 100644 index 2ff6cad50..000000000 --- a/FAQ +++ /dev/null @@ -1,19 +0,0 @@ -Guile FAQ -*- outline -*- - -* Build problems - -** readline.c: error: `rl_pending_input' undeclared - -This occurs if the Readline library detected by Guile's configure -script is actually the BSD Editline project's supposedly -Readline-compatible library. The immediate fix is to uninstall -Editline and install the real GNU Readline instead. When you do this, -please note that it probably won't work to keep Editline in /usr and -install GNU Readline in /usr/local (or some similar arrangement), -because the Editline library will then still be picked up at link and -run time; it's best (subject to other constraints) to remove Editline -completely. - -For the longer term, please also report this problem to the Editline -project, to encourage them to fix it in the next release of their -Readline compatibility library. diff --git a/GUILE-VERSION b/GUILE-VERSION index 9d9539a5c..580a1f506 100644 --- a/GUILE-VERSION +++ b/GUILE-VERSION @@ -2,7 +2,7 @@ GUILE_MAJOR_VERSION=1 GUILE_MINOR_VERSION=9 -GUILE_MICRO_VERSION=0 +GUILE_MICRO_VERSION=2 GUILE_EFFECTIVE_VERSION=${GUILE_MAJOR_VERSION}.${GUILE_MINOR_VERSION} GUILE_VERSION=${GUILE_EFFECTIVE_VERSION}.${GUILE_MICRO_VERSION}-bdwgc diff --git a/HACKING b/HACKING index f6d518531..ffe04a80d 100644 --- a/HACKING +++ b/HACKING @@ -59,8 +59,9 @@ Automake --- a system for automatically generating Makefiles that libtool --- a system for managing the zillion hairy options needed on various systems to produce shared libraries. Available in - "ftp://ftp.gnu.org/pub/gnu/libtool". Version 1.5.26 (or - later) is needed for correct AIX support. + "ftp://ftp.gnu.org/pub/gnu/libtool". Version 2.2 (or + later) is recommended (for correct AIX support, and correct + interaction with the Gnulib module for using libunistring). gettext --- a system for rigging a program so that it can output its messages in the local tongue. Guile presently only exports @@ -88,6 +89,10 @@ have been known to cause problems, and a short description of the problem. - autoreconf from autoconf prior to 2.59 will run gettextize, which will mess up the Guile tree. +- libtool 1.5.26 does not know that it should remove the -R options + that the Gnulib libunistring and havelib modules generate (because + gcc doesn't actually support -R). + - (add here.) diff --git a/LICENSE b/LICENSE index 213e34ae8..3961579b8 100644 --- a/LICENSE +++ b/LICENSE @@ -1,2 +1,2 @@ Guile is covered under the terms of the GNU Lesser General Public -License, version 2.1. See COPYING.LESSER. +License, version 3 or later. See COPYING.LESSER and COPYING. diff --git a/Makefile.am b/Makefile.am index 556b32141..4562dddf3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,39 +1,37 @@ ## Process this file with automake to produce Makefile.in. ## -## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2006, 2007, 2008 Free Software Foundation, Inc. +## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. ## ## This file is part of GUILE. ## -## GUILE 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, or +## GUILE is free software; you can redistribute it and/or modify it +## under the terms of the GNU Lesser General Public License as +## published by the Free Software Foundation; either version 3, or ## (at your option) any later version. ## ## GUILE 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. +## GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU General Public -## License along with GUILE; see the file COPYING. If not, write -## to the Free Software Foundation, Inc., 51 Franklin Street, Fifth -## Floor, Boston, MA 02110-1301 USA +## You should have received a copy of the GNU Lesser General Public +## License along with GUILE; see the file COPYING.LESSER. If not, +## write to the Free Software Foundation, Inc., 51 Franklin Street, +## Fifth Floor, Boston, MA 02110-1301 USA # want automake 1.10 or higher so that AM_GNU_GETTEXT can tell automake that # config.rpath is needed # AUTOMAKE_OPTIONS = 1.10 -SUBDIRS = lib libguile guile-config guile-readline emacs \ - scripts srfi doc examples test-suite benchmark-suite lang am \ +SUBDIRS = lib meta libguile guile-readline emacs \ + srfi doc examples test-suite benchmark-suite lang am \ module testsuite -bin_SCRIPTS = guile-tools - include_HEADERS = libguile.h EXTRA_DIST = LICENSE HACKING GUILE-VERSION \ - m4/ChangeLog-2008 FAQ guile-1.8.pc.in \ + m4/ChangeLog-2008 \ m4/autobuild.m4 ChangeLog-2008 TESTS = check-guile @@ -42,7 +40,16 @@ ACLOCAL_AMFLAGS = -I m4 DISTCLEANFILES = check-guile.log -pkgconfigdir = $(libdir)/pkgconfig -pkgconfig_DATA = guile-1.8.pc +dist-hook: gen-ChangeLog + +gen_start_rev = 61db429e251bfd2f75cb4632972e0238056eb24b +.PHONY: gen-ChangeLog +gen-ChangeLog: + if test -d .git; then \ + $(top_srcdir)/build-aux/gitlog-to-changelog \ + $(gen_start_rev)..HEAD > $(distdir)/cl-t; \ + rm -f $(distdir)/ChangeLog; \ + mv $(distdir)/cl-t $(distdir)/ChangeLog; \ + fi # Makefile.am ends here diff --git a/NEWS b/NEWS index de8e2c13d..353412021 100644 --- a/NEWS +++ b/NEWS @@ -5,29 +5,602 @@ See the end for copying conditions. Please send Guile bug reports to bug-guile@gnu.org. -Changes in 1.9.0: +(During the 1.9 series, we will keep an incremental NEWS for the latest +prerelease, and a full NEWS corresponding to 1.8 -> 2.0.) + +Changes in 1.9.2 (since the 1.9.1 prerelease): + +** VM speed improvements + +Closures now copy the free variables that they need into a flat vector +instead of capturing all heap-allocated variables. This speeds up access +to free variables, avoids unnecessary garbage retention, and allows all +variables to be allocated on the stack. + +Variables which are `set!' are now allocated on the stack, but in +"boxes". This allows a more uniform local variable allocation +discipline, and allows faster access to these variables. + +The VM has new special-case operations, `add1' and `sub1'. + +** VM robustness improvements + +The maximum number of live local variables has been increased from 256 +to 65535. + +The default VM stack size is 64 kilo-words, up from 16 kilo-words. This +allows more programs to execute in the default stack space. In the +future we will probably implement extensible stacks via overflow +handlers. + +Some lingering cases in which the VM could perform unaligned accesses +have been fixed. + +The address range for relative jumps has been expanded from 16-bit +addresses to 19-bit addresses via 8-byte alignment of jump targets. This +will probably change to a 24-bit byte-addressable strategy before Guile +2.0. + +** Compiler optimizations + +Procedures bound by `letrec' are no longer allocated on the heap, +subject to a few constraints. In many cases, procedures bound by +`letrec' and `let' can be rendered inline to their parent function, with +loop detection for mutually tail-recursive procedures. + +Unreferenced variables are now optimized away. + +** Compiler robustness + +Guile may now warn about unused lexically-bound variables. Pass +`-Wunused-variable' to `guile-tools compile', or `#:warnings +(unused-variable)' within the #:opts argument to the `compile' procedure +from `(system base compile)'. + +** Incomplete support for Unicode characters and strings + +Preliminary support for Unicode has landed. Characters may be entered in +octal format via e.g. `#\454', or created via (integer->char 300). A hex +external representation will probably be introduced at some point. + +Internally, strings are now represented either in the `latin-1' +encoding, one byte per character, or in UTF-32, with four bytes per +character. Strings manage their own allocation, switching if needed. + +Currently no locale conversion is performed. Extended characters may be +written in a string using the hexadecimal escapes `\xXX', `\uXXXX', or +`\UXXXXXX', for 8-bit, 16-bit, or 24-bit codepoints, respectively. + +This support is obviously incomplete. Many C functions have not yet been +updated to deal with the new representations. Users are advised to wait +for the next release for more serious use of Unicode strings. + +** `defined?' may accept a module as its second argument + +Previously it only accepted internal structures from the evaluator. + +** `let-values' is now implemented with a hygienic macro + +This could have implications discussed below in the NEWS entry titled, +"Lexical bindings introduced by hygienic macros may not be referenced by +nonhygienic macros". + +** Global variables `scm_charnames' and `scm_charnums' are removed + +These variables contained the names of control characters and were +used when writing characters. While these were global, they were +never intended to be public API. They have been replaced with private +functions. + +** EBCDIC support is removed + +There was an EBCDIC compile flag that altered some of the character +processing. It appeared that full EBCDIC support was never completed +and was unmaintained. + +** Packaging changes + +Guile now provides `guile-2.0.pc' (used by pkg-config) instead of +`guile-1.8.pc'. + +** And of course, the usual collection of bugfixes + +Interested users should see the ChangeLog for more information. + + +Changes in 1.9.x (since the 1.8.x series): * New modules (see the manual for details) -** `(srfi srfi-18)', multithreading support -** The `(ice-9 i18n)' module provides internationalization support - -* Changes to the distribution - -** Guile now uses Gnulib as a portability aid +** `(srfi srfi-18)', more sophisticated multithreading support +** `(ice-9 i18n)', internationalization support +** `(rnrs bytevector)', the R6RS bytevector API +** `(rnrs io ports)', a subset of the R6RS I/O port API +** `(system xref)', a cross-referencing facility (FIXME undocumented) * Changes to the stand-alone interpreter + +** Guile now can compile Scheme to bytecode for a custom virtual machine. + +Compiled code loads much faster than Scheme source code, and runs around +3 or 4 times as fast, generating much less garbage in the process. + +** The stack limit is now initialized from the environment. + +If getrlimit(2) is available and a stack limit is set, Guile will set +its stack limit to 80% of the rlimit. Otherwise the limit is 160000 +words, a four-fold increase from the earlier default limit. + +** New environment variables: GUILE_LOAD_COMPILED_PATH, + GUILE_SYSTEM_LOAD_COMPILED_PATH + +GUILE_LOAD_COMPILED_PATH is for compiled files what GUILE_LOAD_PATH is +for source files. It is a different path, however, because compiled +files are architecture-specific. GUILE_SYSTEM_LOAD_COMPILED_PATH is like +GUILE_SYSTEM_PATH. + +** New read-eval-print loop (REPL) implementation + +Running Guile with no arguments drops the user into the new REPL. While +it is self-documenting to an extent, the new REPL has not yet been +documented in the manual. This will be fixed before 2.0. + +** New `guile-tools' commands: `compile', `disassemble' + +Pass the `--help' command-line option to these commands for more +information. + * Changes to Scheme functions and syntax -** A new 'memoize-symbol evaluator trap has been added. This trap can -be used for efficiently implementing a Scheme code coverage. +** Procedure removed: `the-environment' + +This procedure was part of the interpreter's execution model, and does +not apply to the compiler. + +** Files loaded with `primitive-load-path' will now be compiled + automatically. + +If a compiled .go file corresponding to a .scm file is not found or is +not fresh, the .scm file will be compiled on the fly, and the resulting +.go file stored away. An advisory note will be printed on the console. + +Note that this mechanism depends on preservation of the .scm and .go +modification times; if the .scm or .go files are moved after +installation, care should be taken to preserve their original +timestamps. + +Autocompiled files will be stored in the $XDG_CACHE_HOME/guile/ccache +directory, where $XDG_CACHE_HOME defaults to ~/.cache. This directory +will be created if needed. + +To inhibit autocompilation, set the GUILE_AUTO_COMPILE environment +variable to 0, or pass --no-autocompile on the Guile command line. + +Note that there is currently a bug here: automatic compilation will +sometimes be attempted when it shouldn't. + +For example, the old (lang elisp) modules are meant to be interpreted, +not compiled. This bug will be fixed before 2.0. FIXME 2.0: Should say +something here about module-transformer called for compile. + +** New POSIX procedures: `getrlimit' and `setrlimit' + +Note however that the interface of these functions is likely to change +in the next prerelease. + +** New procedure in `(oops goops)': `method-formals' + +** BUG: (procedure-property func 'arity) does not work on compiled + procedures + +This will be fixed one way or another before 2.0. + +** New procedures in (ice-9 session): `add-value-help-handler!', + `remove-value-help-handler!', `add-name-help-handler!' + `remove-name-help-handler!', `procedure-arguments', + +The value and name help handlers provide some minimal extensibility to +the help interface. Guile-lib's `(texinfo reflection)' uses them, for +example, to make stexinfo help documentation available. See those +procedures' docstrings for more information. + +`procedure-arguments' describes the arguments that a procedure can take, +combining arity and formals. For example: + + (procedure-arguments resolve-interface) + => ((required . (name)) (rest . args)) + +Additionally, `module-commentary' is now publically exported from +`(ice-9 session). + +** Deprecated: `procedure->memoizing-macro', `procedure->syntax' + +These procedures will not work with syncase expansion, and indeed are +not used in the normal course of Guile. They are still used by the old +Emacs Lisp support, however. + +** New language: ECMAScript + +Guile now ships with one other high-level language supported, +ECMAScript. The goal is to support all of version 3.1 of the standard, +but not all of the libraries are there yet. This support is not yet +documented; ask on the mailing list if you are interested. + +** New language: Brainfuck + +Brainfuck is a toy language that closely models Turing machines. Guile's +brainfuck compiler is meant to be an example of implementing other +languages. See the manual for details, or +http://en.wikipedia.org/wiki/Brainfuck for more information about the +Brainfuck language itself. + +** Defmacros may now have docstrings. + +Indeed, any macro may have a docstring. `object-documentation' from +`(ice-9 documentation)' may be used to retrieve the docstring, once you +have a macro value -- but see the above note about first-class macros. +Docstrings are associated with the syntax transformer procedures. + +** The psyntax expander now knows how to interpret the @ and @@ special + forms. + +** The psyntax expander is now hygienic with respect to modules. + +Free variables in a macro are scoped in the module that the macro was +defined in, not in the module the macro is used in. For example, code +like this works now: + + (define-module (foo) #:export (bar)) + (define (helper x) ...) + (define-syntax bar + (syntax-rules () ((_ x) (helper x)))) + + (define-module (baz) #:use-module (foo)) + (bar qux) + +It used to be you had to export `helper' from `(foo)' as well. +Thankfully, this has been fixed. + +** New function, `procedure-module' + +While useful on its own, `procedure-module' is used by psyntax on syntax +transformers to determine the module in which to scope introduced +identifiers. + +** `eval-case' has been deprecated, and replaced by `eval-when'. + +The semantics of `eval-when' are easier to understand. It is still +missing documentation, however. + +** Guile is now more strict about prohibiting definitions in expression + contexts. + +Although previous versions of Guile accepted it, the following +expression is not valid, in R5RS or R6RS: + + (if test (define foo 'bar) (define foo 'baz)) + +In this specific case, it would be better to do: + + (define foo (if test 'bar 'baz)) + +It is certainly possible to circumvent this resriction with e.g. +`(module-define! (current-module) 'foo 'baz)'. We would appreciate +feedback about this change (a consequence of using psyntax as the +default expander), and may choose to revisit this situation before 2.0 +in response to user feedback. + +** Defmacros must now produce valid Scheme expressions. + +It used to be that defmacros could unquote in Scheme values, as a way of +supporting partial evaluation, and avoiding some hygiene issues. For +example: + + (define (helper x) ...) + (define-macro (foo bar) + `(,helper ,bar)) + +Assuming this macro is in the `(baz)' module, the direct translation of +this code would be: + + (define (helper x) ...) + (define-macro (foo bar) + `((@@ (baz) helper) ,bar)) + +Of course, one could just use a hygienic macro instead: + + (define-syntax foo + (syntax-rules () + ((_ bar) (helper bar)))) + +** Guile's psyntax now supports docstrings and internal definitions. + +The following Scheme is not strictly legal: + + (define (foo) + "bar" + (define (baz) ...) + (baz)) + +However its intent is fairly clear. Guile interprets "bar" to be the +docstring of `foo', and the definition of `baz' is still in definition +context. + +** Macros need to be defined before their first use. + +It used to be that with lazy memoization, this might work: + + (define (foo x) + (ref x)) + (define-macro (ref x) x) + (foo 1) => 1 + +But now, the body of `foo' is interpreted to mean a call to the toplevel +`ref' function, instead of a macro expansion. The solution is to define +macros before code that uses them. + +** Functions needed by macros at expand-time need to be present at + expand-time. + +For example, this code will work at the REPL: + + (define (double-helper x) (* x x)) + (define-macro (double-literal x) (double-helper x)) + (double-literal 2) => 4 + +But it will not work when a file is compiled, because the definition of +`double-helper' is not present at expand-time. The solution is to wrap +the definition of `double-helper' in `eval-when': + + (eval-when (load compile eval) + (define (double-helper x) (* x x))) + (define-macro (double-literal x) (double-helper x)) + (double-literal 2) => 4 + +See the (currently missing) documentation for eval-when for more +information. + +** New variable, %pre-modules-transformer + +Need to document this one some more. + +** Temporarily removed functions: `macroexpand', `macroexpand-1' + +`macroexpand' will be added back before 2.0. It is unclear how to +implement `macroexpand-1' with syntax-case, though PLT Scheme does prove +that it is possible. + +** New reader macros: #' #` #, #,@ + +These macros translate, respectively, to `syntax', `quasisyntax', +`unsyntax', and `unsyntax-splicing'. See the R6RS for more information. +These reader macros may be overridden by `read-hash-extend'. + +** Incompatible change to #' + +Guile did have a #' hash-extension, by default, which just returned the +subsequent datum: #'foo => foo. In the unlikely event that anyone +actually used this, this behavior may be reinstated via the +`read-hash-extend' mechanism. + +** Scheme expresssions may be commented out with #; + +#; comments out an entire expression. See SRFI-62 or the R6RS for more +information. + +** `make-stack' with a tail-called procedural narrowing argument no longer + works (with compiled procedures) + +It used to be the case that a captured stack could be narrowed to select +calls only up to or from a certain procedure, even if that procedure +already tail-called another procedure. This was because the debug +information from the original procedure was kept on the stack. + +Now with the new compiler, the stack only contains active frames from +the current continuation. A narrow to a procedure that is not in the +stack will result in an empty stack. To fix this, narrow to a procedure +that is active in the current continuation, or narrow to a specific +number of stack frames. + +** backtraces through compiled procedures only show procedures that are + active in the current continuation + +Similarly to the previous issue, backtraces in compiled code may be +different from backtraces in interpreted code. There are no semantic +differences, however. Please mail bug-guile@gnu.org if you see any +deficiencies with Guile's backtraces. + +** syntax-rules and syntax-case macros now propagate source information + through to the expanded code + +This should result in better backtraces. + +** The currying behavior of `define' has been removed. + +Before, `(define ((f a) b) (* a b))' would translate to + + (define f (lambda (a) (lambda (b) (* a b)))) + +Now a syntax error is signaled, as this syntax is not supported by +default. If there is sufficient demand, this syntax can be supported +again by default. + +** All modules have names now + +Before, you could have anonymous modules: modules without names. Now, +because of hygiene and macros, all modules have names. If a module was +created without a name, the first time `module-name' is called on it, a +fresh name will be lazily generated for it. + +** Many syntax errors have different texts now + +Syntax errors still throw to the `syntax-error' key, but the arguments +are often different now. Perhaps in the future, Guile will switch to +using standard SRFI-35 conditions. + +** Returning multiple values to compiled code will silently truncate the + values to the expected number + +For example, the interpreter would raise an error evaluating the form, +`(+ (values 1 2) (values 3 4))', because it would see the operands as +being two compound "values" objects, to which `+' does not apply. + +The compiler, on the other hand, receives multiple values on the stack, +not as a compound object. Given that it must check the number of values +anyway, if too many values are provided for a continuation, it chooses +to truncate those values, effectively evaluating `(+ 1 3)' instead. + +The idea is that the semantics that the compiler implements is more +intuitive, and the use of the interpreter will fade out with time. +This behavior is allowed both by the R5RS and the R6RS. + +** Multiple values in compiled code are not represented by compound + objects + +This change may manifest itself in the following situation: + + (let ((val (foo))) (do-something) val) + +In the interpreter, if `foo' returns multiple values, multiple values +are produced from the `let' expression. In the compiler, those values +are truncated to the first value, and that first value is returned. In +the compiler, if `foo' returns no values, an error will be raised, while +the interpreter would proceed. + +Both of these behaviors are allowed by R5RS and R6RS. The compiler's +behavior is more correct, however. If you wish to preserve a potentially +multiply-valued return, you will need to set up a multiple-value +continuation, using `call-with-values'. + +** Defmacros are now implemented in terms of syntax-case. + +The practical ramification of this is that the `defmacro?' predicate has +been removed, along with `defmacro-transformer', `macro-table', +`xformer-table', `assert-defmacro?!', `set-defmacro-transformer!' and +`defmacro:transformer'. This is because defmacros are simply macros. If +any of these procedures provided useful facilities to you, we encourage +you to contact the Guile developers. + +** psyntax is now the default expander + +Scheme code is now expanded by default by the psyntax hygienic macro +expander. Expansion is performed completely before compilation or +interpretation. + +Notably, syntax errors will be signalled before interpretation begins. +In the past, many syntax errors were only detected at runtime if the +code in question was memoized. + +As part of its expansion, psyntax renames all lexically-bound +identifiers. Original identifier names are preserved and given to the +compiler, but the interpreter will see the renamed variables, e.g., +`x432' instead of `x'. + +Note that the psyntax that Guile uses is a fork, as Guile already had +modules before incompatible modules were added to psyntax -- about 10 +years ago! Thus there are surely a number of bugs that have been fixed +in psyntax since then. If you find one, please notify bug-guile@gnu.org. + +** syntax-rules and syntax-case are available by default. + +There is no longer any need to import the `(ice-9 syncase)' module +(which is now deprecated). The expander may be invoked directly via +`sc-expand', though it is normally searched for via the current module +transformer. + +Also, the helper routines for syntax-case are available in the default +environment as well: `syntax->datum', `datum->syntax', +`bound-identifier=?', `free-identifier=?', `generate-temporaries', +`identifier?', and `syntax-violation'. See the R6RS for documentation. + +** Lexical bindings introduced by hygienic macros may not be referenced + by nonhygienic macros. + +If a lexical binding is introduced by a hygienic macro, it may not be +referenced by a nonhygienic macro. For example, this works: + + (let () + (define-macro (bind-x val body) + `(let ((x ,val)) ,body)) + (define-macro (ref x) + x) + (bind-x 10 (ref x))) + +But this does not: + + (let () + (define-syntax bind-x + (syntax-rules () + ((_ val body) (let ((x val)) body)))) + (define-macro (ref x) + x) + (bind-x 10 (ref x))) + +It is not normal to run into this situation with existing code. However, +as code is ported over from defmacros to syntax-case, it is possible to +run into situations like this. In the future, Guile will probably port +its `while' macro to syntax-case, which makes this issue one to know +about. + +** Macros may no longer be referenced as first-class values. + +In the past, you could evaluate e.g. `if', and get its macro value. Now, +expanding this form raises a syntax error. + +Macros still /exist/ as first-class values, but they must be +/referenced/ via the module system, e.g. `(module-ref (current-module) +'if)'. + +This decision may be revisited before the 2.0 release. Feedback welcome +to guile-devel@gnu.org (subscription required) or bug-guile@gnu.org (no +subscription required). + +** New macro type: syncase-macro + +XXX Need to decide whether to document this for 2.0, probably should: +make-syncase-macro, make-extended-syncase-macro, macro-type, +syncase-macro-type, syncase-macro-binding + +** A new `memoize-symbol' evaluator trap has been added. + +This trap can be used for efficiently implementing a Scheme code +coverage. ** Duplicate bindings among used modules are resolved lazily. + This slightly improves program startup times. ** New thread cancellation and thread cleanup API + See `cancel-thread', `set-thread-cleanup!', and `thread-cleanup'. +** Fix bad interaction between `false-if-exception' and stack-call. + +Exceptions thrown by `false-if-exception' were erronously causing the +stack to be saved, causing later errors to show the incorrectly-saved +backtrace. This has been fixed. + +** New global variables: %load-compiled-path, %load-compiled-extensions + +These are analogous to %load-path and %load-extensions. + +** New procedure, `make-promise' + +`(make-promise (lambda () foo))' is equivalent to `(delay foo)'. + +** New entry into %guile-build-info: `ccachedir' + +** Fix bug in `module-bound?'. + +`module-bound?' was returning true if a module did have a local +variable, but one that was unbound, but another imported module bound +the variable. This was an error, and was fixed. + +** `(ice-9 syncase)' has been deprecated. + +As syntax-case is available by default, importing `(ice-9 syncase)' has +no effect, and will trigger a deprecation warning. + * Changes to the C interface ** The GH interface (deprecated in version 1.6, 2001) was removed. @@ -40,22 +613,80 @@ application code. ** Functions for handling `scm_option' now no longer require an argument indicating length of the `scm_t_option' array. -** Primitive procedures (aka. "subrs") are now stored in double cells -This removes the subr table and simplifies the code. +** scm_primitive_load_path has additional argument, exception_on_error -** Primitive procedures with more than 3 arguments (aka. "gsubrs") are -no longer implemented using the "compiled closure" mechanism. This -simplifies code and reduces both the storage and run-time overhead. +** New C function: scm_module_public_interface + +This procedure corresponds to Scheme's `module-public-interface'. + +** `scm_stat' has an additional argument, `exception_on_error' +** `scm_primitive_load_path' has an additional argument `exception_on_not_found' + +** `scm_set_port_seek' and `scm_set_port_truncate' use the `scm_t_off' type + +Previously they would use the `off_t' type, which is fragile since its +definition depends on the application's value for `_FILE_OFFSET_BITS'. + +** The `long_long' C type, deprecated in 1.8, has been removed + +* Changes to the distribution + +** Guile's license is now LGPLv3+ + +In other words the GNU Lesser General Public License, version 3 or +later (at the discretion of each person that chooses to redistribute +part of Guile). + +** `guile-config' will be deprecated in favor of `pkg-config' + +`guile-config' has been rewritten to get its information from +`pkg-config', so this should be a transparent change. Note however that +guile.m4 has yet to be modified to call pkg-config instead of +guile-config. + +** Guile now provides `guile-2.0.pc' instead of `guile-1.8.pc' + +Programs that use `pkg-config' to find Guile or one of its Autoconf +macros should now require `guile-2.0' instead of `guile-1.8'. + +** New installation directory: $(pkglibdir)/1.9/ccache + +If $(libdir) is /usr/lib, for example, Guile will install its .go files +to /usr/lib/guile/1.9/ccache. These files are architecture-specific. + +** New dependency: GNU libunistring. + +See http://www.gnu.org/software/libunistring/. We hope to merge in +Unicode support in the next prerelease. + + + +Changes in 1.8.8 (since 1.8.7) + +* Bugs fixed + +** Fix possible buffer overruns when parsing numbers Changes in 1.8.7 (since 1.8.6) +* New modules (see the manual for details) + +** `(srfi srfi-98)', an interface to access environment variables + * Bugs fixed +** Fix compilation with `--disable-deprecated' ** Fix %fast-slot-ref/set!, to avoid possible segmentation fault ** Fix MinGW build problem caused by HAVE_STRUCT_TIMESPEC confusion ** Fix build problem when scm_t_timespec is different from struct timespec ** Fix build when compiled with -Wundef -Werror +** More build fixes for `alphaev56-dec-osf5.1b' (Tru64) +** Build fixes for `powerpc-ibm-aix5.3.0.0' (AIX 5.3) +** With GCC, always compile with `-mieee' on `alpha*' and `sh*' +** Better diagnose broken `(strftime "%z" ...)' in `time.test' (bug #24130) +** Fix parsing of SRFI-88/postfix keywords longer than 128 characters +** Fix reading of complex numbers where both parts are inexact decimals ** Allow @ macro to work with (ice-9 syncase) @@ -184,13 +815,6 @@ lead to a stack overflow. ** Fixed shadowing of libc's on Tru64, which broke compilation ** Make sure all tests honor `$TMPDIR' -* Changes to the distribution - -** New FAQ - -We've started collecting Frequently Asked Questions (FAQ), and will -distribute these (with answers!) in future Guile releases. - Changes in 1.8.4 (since 1.8.3) diff --git a/README b/README index 3af511b38..1f71b8afe 100644 --- a/README +++ b/README @@ -14,7 +14,7 @@ Guile versions with an odd middle number, i.e. 1.9.* are unstable development versions. Even middle numbers indicate stable versions. This has been the case since the 1.3.* series. -The next stable release will likely be version 1.10.0. +The next stable release will likely be version 2.0.0. Please send bug reports to bug-guile@gnu.org. @@ -27,24 +27,38 @@ Generic instructions for configuring and compiling Guile can be found in the INSTALL file. Guile specific information and configure options can be found below, including instructions for installing SLIB. -Guile requires a few external packages and can optionally use a number -of external packages such as `readline' when they are available. -Guile expects to be able to find these packages in the default -compiler setup, it does not try to make any special arrangements -itself. For example, for the `readline' package, Guile expects to be -able to find the include file , without passing -any special `-I' options to the compiler. +Guile depends on the following external libraries. +- libgmp +- libiconv +- libintl +- libltdl +- libunistring +It will also use the libreadline library if it is available. For each +of these there is a corresponding --with-XXX-prefix option that you +can use when invoking ./configure, if you have these libraries +installed in a location other than the standard places (/usr and +/usr/local). -If you installed an external package, and you used the --prefix -installation option to install it somewhere else than /usr/local, you -must arrange for your compiler to find it by default. If that -compiler is gcc, one convenient way of making such arrangements is to -use the --with-local-prefix option during installation, naming the -same directory as you used in the --prefix option of the package. In -particular, it is not good enough to use the same --prefix option when -you install gcc and the package; you need to use the ---with-local-prefix option as well. See the gcc documentation for -more details. +These options are provided by the Gnulib `havelib' module, and details +of how they work are documented in `Searching for Libraries' in the +Gnulib manual (http://www.gnu.org/software/gnulib/manual). The extent +to which they work on a given OS depends on whether that OS supports +encoding full library path names in executables (aka `rpath'). Also +note that using these options, and hence hardcoding full library path +names (where that is supported), makes it impossible to later move the +built executables and libraries to an installation location other than +the one that was specified at build time. + +Another possible approach is to set CPPFLAGS and LDFLAGS before +running configure, so that they include -I options for all the +non-standard places where you have installed header files and -L +options for all the non-standard places where you have installed +libraries. This will allow configure and make to find those headers +and libraries during the build. The locations found will not be +hardcoded into the build executables and libraries, so with this +approach you will probably also need to set LD_LIBRARY_PATH +correspondingly, to allow Guile to find the necessary libraries again +at runtime. Required External Packages ================================================ @@ -61,6 +75,12 @@ Guile requires the following external packages: libltdl is used for loading extensions at run-time. It is available from http://www.gnu.org/software/libtool/ + - GNU libunistring + + libunistring is used for Unicode string operations, such as the + `utf*->string' procedures. It is available from + http://www.gnu.org/software/libunistring/ . + Special Instructions For Some Systems ===================================== @@ -223,9 +243,23 @@ GUILE_FOR_BUILD variable, it defaults to just "guile". Using Guile Without Installing It ========================================= -The top directory of the Guile sources contains a script called -"pre-inst-guile" that can be used to run the Guile that has just been -built. +The "meta/" subdirectory of the Guile sources contains a script called +"guile" that can be used to run the Guile that has just been built. Note +that this is not the same "guile" as the one that is installed; this +"guile" is a wrapper script that sets up the environment appropriately, +then invokes the Guile binary. + +You may also build external packages against an uninstalled Guile build +tree. The "uninstalled-env" script in the "meta/" subdirectory will set +up an environment with a path including "meta/", a modified dynamic +linker path, a modified PKG_CONFIG_PATH, etc. + +For example, you can enter this environment via invoking + + meta/uninstalled-env bash + +Within that shell, other packages should be able to build against +uninstalled Guile. Installing SLIB =========================================================== @@ -289,6 +323,7 @@ About This Distribution ============================================== Interesting files include: - LICENSE, which contains the exact terms of the Guile license. +- COPYING.LESSER, which contains the terms of the GNU Lesser General Public License. - COPYING, which contains the terms of the GNU General Public License. - INSTALL, which contains general instructions for building/installing Guile. - NEWS, which describes user-visible changes since the last release of Guile. diff --git a/THANKS b/THANKS index d93837d3b..e458a7625 100644 --- a/THANKS +++ b/THANKS @@ -3,6 +3,7 @@ Contributors since the last release: Rob Browning Ludovic Courtès Julian Graham + Mike Gran Stefan Jahn Neil Jerram Gregory Marton @@ -13,6 +14,7 @@ Contributors since the last release: Kevin Ryde Bill Schottstaedt Richard Todd + Andy Wingo Sponsors since the last release: @@ -23,6 +25,7 @@ For fixes or providing information which led to a fix: David Allouche Martin Baulig Fabrice Bauzac + Sylvain Beucler Carlo Bramini Rob Browning Adrian Bunk @@ -37,6 +40,7 @@ For fixes or providing information which led to a fix: John W Eaton Clinton Ebadi David Fang + Barry Fishman Charles Gagnon Peter Gavin Eric Gillespie, Jr @@ -61,10 +65,12 @@ For fixes or providing information which led to a fix: René Köcher Matthias Köppe Matt Kraai + Daniel Kraft Miroslav Lichvar Jeff Long Marco Maggi Gregory Marton + Kjetil S. Matheussen Antoine Mathys Dan McMahill Roger Mc Murtrie @@ -82,6 +88,7 @@ For fixes or providing information which led to a fix: David Pirotte Carlos Pita Ken Raeburn + Juhani Rantanen Andreas Rottmann Hugh Sasse Werner Scheinast @@ -91,6 +98,7 @@ For fixes or providing information which led to a fix: Scott Shedden Alex Shinn Daniel Skarda + Dale Smith Cesar Strauss Rainer Tammer Richard Todd @@ -106,6 +114,7 @@ For fixes or providing information which led to a fix: Andreas Vögele Michael Talbot-Wilson Michael Tuexen + Mark H. Weaver Jon Wilson Andy Wingo Keith Wright diff --git a/am/Makefile.am b/am/Makefile.am index 2c49adb09..d1b7eccc7 100644 --- a/am/Makefile.am +++ b/am/Makefile.am @@ -4,20 +4,20 @@ ## ## This file is part of GUILE. ## -## GUILE 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, or +## GUILE is free software; you can redistribute it and/or modify it +## under the terms of the GNU Lesser General Public License as +## published by the Free Software Foundation; either version 3, or ## (at your option) any later version. ## ## GUILE 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. +## GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU General Public -## License along with GUILE; see the file COPYING. If not, write -## to the Free Software Foundation, Inc., 51 Franklin Street, Fifth -## Floor, Boston, MA 02110-1301 USA +## You should have received a copy of the GNU Lesser General Public +## License along with GUILE; see the file COPYING.LESSER. If not, +## write to the Free Software Foundation, Inc., 51 Franklin Street, +## Fifth Floor, Boston, MA 02110-1301 USA AUTOMAKE_OPTIONS = gnu diff --git a/am/guilec b/am/guilec index 939ea76c4..ce0711b74 100644 --- a/am/guilec +++ b/am/guilec @@ -2,12 +2,32 @@ GOBJECTS = $(SOURCES:%.scm=%.go) moddir = $(pkgdatadir)/$(GUILE_EFFECTIVE_VERSION)/$(modpath) -nobase_mod_DATA = $(SOURCES) $(NOCOMP_SOURCES) $(GOBJECTS) +nobase_mod_DATA = $(SOURCES) $(NOCOMP_SOURCES) +ccachedir = $(pkglibdir)/$(GUILE_EFFECTIVE_VERSION)/ccache/$(modpath) +nobase_ccache_DATA = $(GOBJECTS) EXTRA_DIST = $(SOURCES) $(NOCOMP_SOURCES) CLEANFILES = $(GOBJECTS) +# Well, shit. We can't have install changing timestamps, can we? But +# install_sh doesn't know how to preserve timestamps. Soooo, fondle +# automake to make things happen. +install-data-hook: + @$(am__vpath_adj_setup) \ + list='$(nobase_mod_DATA)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + $(am__vpath_adj) \ + echo " touch -r '$$d$$p' '$(DESTDIR)$(moddir)/$$f'"; \ + touch -r "$$d$$p" "$(DESTDIR)$(moddir)/$$f"; \ + done + @$(am__vpath_adj_setup) \ + list='$(nobase_ccache_DATA)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + $(am__vpath_adj) \ + echo " touch -r '$$d$$p' '$(DESTDIR)$(ccachedir)/$$f'"; \ + touch -r "$$d$$p" "$(DESTDIR)$(ccachedir)/$$f"; \ + done + SUFFIXES = .scm .go .scm.go: - $(MKDIR_P) `dirname $@` - $(top_builddir)/pre-inst-guile-env $(top_builddir)/guile-tools compile -o "$@" "$<" + GUILE_AUTO_COMPILE=0 $(top_builddir)/meta/uninstalled-env guile-tools compile -o "$@" "$<" diff --git a/am/maintainer-dirs b/am/maintainer-dirs index c64268de9..f1b741be7 100644 --- a/am/maintainer-dirs +++ b/am/maintainer-dirs @@ -5,17 +5,17 @@ ## This file is part of GUILE. ## ## GUILE 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, or +## it under the terms of the GNU Lesser General Public License as +## published by the Free Software Foundation; either version 3, or ## (at your option) any later version. ## ## GUILE 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. +## GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU General Public -## License along with GUILE; see the file COPYING. If not, write +## You should have received a copy of the GNU Lesser General Public +## License along with GUILE; see the file COPYING.LESSER. If not, write ## to the Free Software Foundation, Inc., 51 Franklin Street, Fifth ## Floor, Boston, MA 02110-1301 USA diff --git a/am/pre-inst-guile b/am/pre-inst-guile index c1a7407c9..7993d1531 100644 --- a/am/pre-inst-guile +++ b/am/pre-inst-guile @@ -5,17 +5,17 @@ ## This file is part of GUILE. ## ## GUILE 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, or +## it under the terms of the GNU Lesser General Public License as +## published by the Free Software Foundation; either version 3, or ## (at your option) any later version. ## ## GUILE 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. +## GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU General Public -## License along with GUILE; see the file COPYING. If not, write +## You should have received a copy of the GNU Lesser General Public +## License along with GUILE; see the file COPYING.LESSER. If not, write ## to the Free Software Foundation, Inc., 51 Franklin Street, Fifth ## Floor, Boston, MA 02110-1301 USA @@ -28,7 +28,7 @@ ## Code: -preinstguile = $(top_builddir_absolute)/pre-inst-guile +preinstguile = $(top_builddir_absolute)/meta/guile preinstguiletool = GUILE="$(preinstguile)" $(top_srcdir)/scripts ## am/pre-inst-guile ends here diff --git a/benchmark-suite/Makefile.am b/benchmark-suite/Makefile.am index e65e8bcb2..dcadd5869 100644 --- a/benchmark-suite/Makefile.am +++ b/benchmark-suite/Makefile.am @@ -1,4 +1,5 @@ SCM_BENCHMARKS = benchmarks/0-reference.bm \ + benchmarks/bytevectors.bm \ benchmarks/continuations.bm \ benchmarks/if.bm \ benchmarks/logand.bm \ diff --git a/benchmark-suite/benchmarks/bytevectors.bm b/benchmark-suite/benchmarks/bytevectors.bm new file mode 100644 index 000000000..a686a08c9 --- /dev/null +++ b/benchmark-suite/benchmarks/bytevectors.bm @@ -0,0 +1,100 @@ +;;; -*- mode: scheme; coding: latin-1; -*- +;;; R6RS Byte Vectors. +;;; +;;; Copyright 2009 Ludovic Courtès +;;; +;;; +;;; This program is free software; you can redistribute it and/or +;;; modify it under the terms of the GNU Lesser General Public License +;;; as published by the Free Software Foundation; either version 3, 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 Lesser General Public License for more details. +;;; +;;; You should have received a copy of the GNU Lesser General Public +;;; License along with this software; see the file COPYING.LESSER. If +;;; not, write to the Free Software Foundation, Inc., 51 Franklin +;;; Street, Fifth Floor, Boston, MA 02110-1301 USA + +(define-module (benchmarks bytevector) + :use-module (rnrs bytevector) + :use-module (srfi srfi-4) + :use-module (benchmark-suite lib)) + +(define bv (make-bytevector 16384)) + +(define %native-endianness + (native-endianness)) + +(define %foreign-endianness + (if (eq? (native-endianness) (endianness little)) + (endianness big) + (endianness little))) + +(define u8v (make-u8vector 16384)) +(define u16v (make-u16vector 8192)) +(define u32v (make-u32vector 4196)) +(define u64v (make-u64vector 2048)) + + +(with-benchmark-prefix "ref/set!" + + (benchmark "bytevector-u8-ref" 1000000 + (bytevector-u8-ref bv 0)) + + (benchmark "bytevector-u16-ref (foreign)" 1000000 + (bytevector-u16-ref bv 0 %foreign-endianness)) + + (benchmark "bytevector-u16-ref (native)" 1000000 + (bytevector-u16-ref bv 0 %native-endianness)) + + (benchmark "bytevector-u16-native-ref" 1000000 + (bytevector-u16-native-ref bv 0)) + + (benchmark "bytevector-u32-ref (foreign)" 1000000 + (bytevector-u32-ref bv 0 %foreign-endianness)) + + (benchmark "bytevector-u32-ref (native)" 1000000 + (bytevector-u32-ref bv 0 %native-endianness)) + + (benchmark "bytevector-u32-native-ref" 1000000 + (bytevector-u32-native-ref bv 0)) + + (benchmark "bytevector-u64-ref (foreign)" 1000000 + (bytevector-u64-ref bv 0 %foreign-endianness)) + + (benchmark "bytevector-u64-ref (native)" 1000000 + (bytevector-u64-ref bv 0 %native-endianness)) + + (benchmark "bytevector-u64-native-ref" 1000000 + (bytevector-u16-native-ref bv 0))) + + +(with-benchmark-prefix "lists" + + (benchmark "bytevector->u8-list" 2000 + (bytevector->u8-list bv)) + + (benchmark "bytevector->uint-list 16-bit" 2000 + (bytevector->uint-list bv (native-endianness) 2)) + + (benchmark "bytevector->uint-list 64-bit" 2000 + (bytevector->uint-list bv (native-endianness) 8))) + + +(with-benchmark-prefix "SRFI-4" ;; for comparison + + (benchmark "u8vector-ref" 1000000 + (u8vector-ref u8v 0)) + + (benchmark "u16vector-ref" 1000000 + (u16vector-ref u16v 0)) + + (benchmark "u32vector-ref" 1000000 + (u32vector-ref u32v 0)) + + (benchmark "u64vector-ref" 1000000 + (u64vector-ref u64v 0))) diff --git a/benchmark-suite/benchmarks/read.bm b/benchmark-suite/benchmarks/read.bm index cb876b5ad..f11ca687a 100644 --- a/benchmark-suite/benchmarks/read.bm +++ b/benchmark-suite/benchmarks/read.bm @@ -2,20 +2,20 @@ ;;; ;;; Copyright (C) 2008 Free Software Foundation, Inc. ;;; -;;; 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 2, or (at your option) -;;; any later version. +;;; This program is free software; you can redistribute it and/or +;;; modify it under the terms of the GNU Lesser General Public License +;;; as published by the Free Software Foundation; either version 3, 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. +;;; GNU Lesser General Public License for more details. ;;; -;;; You should have received a copy of the GNU General Public License -;;; along with this software; see the file COPYING. If not, write to -;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;; Boston, MA 02110-1301 USA +;;; You should have received a copy of the GNU Lesser General Public +;;; License along with this software; see the file COPYING.LESSER. If +;;; not, write to the Free Software Foundation, Inc., 51 Franklin +;;; Street, Fifth Floor, Boston, MA 02110-1301 USA (define-module (benchmarks read) :use-module (benchmark-suite lib)) diff --git a/benchmark-suite/benchmarks/subr.bm b/benchmark-suite/benchmarks/subr.bm index 9c87a9921..ea0045650 100644 --- a/benchmark-suite/benchmarks/subr.bm +++ b/benchmark-suite/benchmarks/subr.bm @@ -2,20 +2,20 @@ ;;; ;;; Copyright (C) 2009 Free Software Foundation, Inc. ;;; -;;; 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 2, or (at your option) -;;; any later version. +;;; This program is free software; you can redistribute it and/or +;;; modify it under the terms of the GNU Lesser General Public License +;;; as published by the Free Software Foundation; either version 3, 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. +;;; GNU Lesser General Public License for more details. ;;; -;;; You should have received a copy of the GNU General Public License -;;; along with this software; see the file COPYING. If not, write to -;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;; Boston, MA 02110-1301 USA +;;; You should have received a copy of the GNU Lesser General Public +;;; License along with this software; see the file COPYING.LESSER. If +;;; not, write to the Free Software Foundation, Inc., 51 Franklin +;;; Street, Fifth Floor, Boston, MA 02110-1301 USA (define-module (benchmarks subrs) :use-module (benchmark-suite lib)) diff --git a/benchmark-suite/benchmarks/uniform-vector-read.bm b/benchmark-suite/benchmarks/uniform-vector-read.bm index d288f0b44..d188b2b86 100644 --- a/benchmark-suite/benchmarks/uniform-vector-read.bm +++ b/benchmark-suite/benchmarks/uniform-vector-read.bm @@ -2,20 +2,20 @@ ;;; ;;; Copyright (C) 2008 Free Software Foundation, Inc. ;;; -;;; 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 2, or (at your option) -;;; any later version. +;;; This program is free software; you can redistribute it and/or +;;; modify it under the terms of the GNU Lesser General Public License +;;; as published by the Free Software Foundation; either version 3, 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. +;;; GNU Lesser General Public License for more details. ;;; -;;; You should have received a copy of the GNU General Public License -;;; along with this software; see the file COPYING. If not, write to -;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;; Boston, MA 02110-1301 USA +;;; You should have received a copy of the GNU Lesser General Public +;;; License along with this software; see the file COPYING.LESSER. If +;;; not, write to the Free Software Foundation, Inc., 51 Franklin +;;; Street, Fifth Floor, Boston, MA 02110-1301 USA (define-module (benchmarks uniform-vector-read) :use-module (benchmark-suite lib) diff --git a/benchmark-suite/guile-benchmark b/benchmark-suite/guile-benchmark index c4c6f23de..41cae06a1 100755 --- a/benchmark-suite/guile-benchmark +++ b/benchmark-suite/guile-benchmark @@ -7,20 +7,20 @@ ;;;; ;;;; Copyright (C) 2002, 2006 Free Software Foundation, Inc. ;;;; -;;;; 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 2, or (at your option) -;;;; any later version. +;;;; This program is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3, 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. +;;;; GNU Lesser General Public License for more details. ;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this software; see the file COPYING. If not, write to -;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;;; Boston, MA 02110-1301 USA +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this software; see the file COPYING.LESSER. +;;;; If not, write to the Free Software Foundation, Inc., 51 Franklin +;;;; Street, Fifth Floor, Boston, MA 02110-1301 USA ;;;; Usage: [guile -e main -s] guile-benchmark [OPTIONS] [BENCHMARK ...] diff --git a/benchmark-suite/lib.scm b/benchmark-suite/lib.scm index 65491d735..65253c5ff 100644 --- a/benchmark-suite/lib.scm +++ b/benchmark-suite/lib.scm @@ -1,20 +1,20 @@ ;;;; benchmark-suite/lib.scm --- generic support for benchmarking ;;;; Copyright (C) 2002, 2006 Free Software Foundation, Inc. ;;;; -;;;; 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 2, or (at your option) -;;;; any later version. +;;;; This program is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3, 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. +;;;; GNU Lesser General Public License for more details. ;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this software; see the file COPYING. If not, write to -;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;;; Boston, MA 02110-1301 USA +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this software; see the file COPYING.LESSER. +;;;; If not, write to the Free Software Foundation, Inc., 51 Franklin +;;;; Street, Fifth Floor, Boston, MA 02110-1301 USA (define-module (benchmark-suite lib) :export ( diff --git a/build-aux/config.rpath b/build-aux/config.rpath index 35f959b87..85c2f209b 100755 --- a/build-aux/config.rpath +++ b/build-aux/config.rpath @@ -47,7 +47,7 @@ for cc_temp in $CC""; do done cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'` -# Code taken from libtool.m4's AC_LIBTOOL_PROG_COMPILER_PIC. +# Code taken from libtool.m4's _LT_COMPILER_PIC. wl= if test "$GCC" = yes; then @@ -64,7 +64,7 @@ else ;; esac ;; - mingw* | cygwin* | pw32* | os2*) + mingw* | cygwin* | pw32* | os2* | cegcc*) ;; hpux9* | hpux10* | hpux11*) wl='-Wl,' @@ -76,7 +76,13 @@ else ;; linux* | k*bsd*-gnu) case $cc_basename in - icc* | ecc*) + ecc*) + wl='-Wl,' + ;; + icc* | ifort*) + wl='-Wl,' + ;; + lf95*) wl='-Wl,' ;; pgcc | pgf77 | pgf90) @@ -124,7 +130,7 @@ else esac fi -# Code taken from libtool.m4's AC_LIBTOOL_PROG_LD_SHLIBS. +# Code taken from libtool.m4's _LT_LINKER_SHLIBS. hardcode_libdir_flag_spec= hardcode_libdir_separator= @@ -132,7 +138,7 @@ hardcode_direct=no hardcode_minus_L=no case "$host_os" in - cygwin* | mingw* | pw32*) + 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++. @@ -182,7 +188,7 @@ if test "$with_gnu_ld" = yes; then ld_shlibs=no fi ;; - cygwin* | mingw* | pw32*) + cygwin* | mingw* | pw32* | cegcc*) # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. hardcode_libdir_flag_spec='-L$libdir' @@ -326,7 +332,7 @@ else ;; bsdi[45]*) ;; - cygwin* | mingw* | pw32*) + 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 @@ -494,7 +500,7 @@ else fi # Check dynamic linker characteristics -# Code taken from libtool.m4's AC_LIBTOOL_SYS_DYNAMIC_LINKER. +# Code taken from libtool.m4's _LT_SYS_DYNAMIC_LINKER. # Unlike libtool.m4, here we don't care about _all_ names of the library, but # only about the one the linker finds when passed -lNAME. This is the last # element of library_names_spec in libtool.m4, or possibly two of them if the @@ -517,7 +523,7 @@ case "$host_os" in bsdi[45]*) library_names_spec='$libname$shrext' ;; - cygwin* | mingw* | pw32*) + cygwin* | mingw* | pw32* | cegcc*) shrext=.dll library_names_spec='$libname.dll.a $libname.lib' ;; diff --git a/build-aux/gitlog-to-changelog b/build-aux/gitlog-to-changelog new file mode 100755 index 000000000..1cc53eb7c --- /dev/null +++ b/build-aux/gitlog-to-changelog @@ -0,0 +1,183 @@ +#!/usr/bin/perl +# Convert git log output to ChangeLog format. + +my $VERSION = '2009-06-04 08:53'; # UTC +# The definition above must lie within the first 8 lines in order +# for the Emacs time-stamp write hook (at end) to update it. +# If you change this file with Emacs, please let the write hook +# do its job. Otherwise, update this string manually. + +# Copyright (C) 2008, 2009 Free Software Foundation, Inc. + +# 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 . + +# Written by Jim Meyering + +use strict; +use warnings; +use Getopt::Long; +use POSIX qw(strftime); + +(my $ME = $0) =~ s|.*/||; + +# use File::Coda; # http://meyering.net/code/Coda/ +END { + defined fileno STDOUT or return; + close STDOUT and return; + warn "$ME: failed to close standard output: $!\n"; + $? ||= 1; +} + +sub usage ($) +{ + my ($exit_code) = @_; + my $STREAM = ($exit_code == 0 ? *STDOUT : *STDERR); + if ($exit_code != 0) + { + print $STREAM "Try `$ME --help' for more information.\n"; + } + else + { + print $STREAM < ChangeLog + $ME -- -n 5 foo > last-5-commits-to-branch-foo + +EOF + } + exit $exit_code; +} + +# If the string $S is a well-behaved file name, simply return it. +# If it contains white space, quotes, etc., quote it, and return the new string. +sub shell_quote($) +{ + my ($s) = @_; + if ($s =~ m![^\w+/.,-]!) + { + # Convert each single quote to '\'' + $s =~ s/\'/\'\\\'\'/g; + # Then single quote the string. + $s = "'$s'"; + } + return $s; +} + +sub quoted_cmd(@) +{ + return join (' ', map {shell_quote $_} @_); +} + +{ + my $since_date = '1970-01-01 UTC'; + GetOptions + ( + help => sub { usage 0 }, + version => sub { print "$ME version $VERSION\n"; exit }, + 'since=s' => \$since_date, + ) or usage 1; + + my @cmd = (qw (git log --log-size), "--since=$since_date", + '--pretty=format:%ct %an <%ae>%n%n%s%n%b%n', @ARGV); + open PIPE, '-|', @cmd + or die ("$ME: failed to run `". quoted_cmd (@cmd) ."': $!\n" + . "(Is your Git too old? Version 1.5.1 or later is required.)\n"); + + my $prev_date_line = ''; + while (1) + { + defined (my $in = ) + or last; + $in =~ /^log size (\d+)$/ + or die "$ME:$.: Invalid line (expected log size):\n$in"; + my $log_nbytes = $1; + + my $log; + my $n_read = read PIPE, $log, $log_nbytes; + $n_read == $log_nbytes + or die "$ME:$.: unexpected EOF\n"; + + my @line = split "\n", $log; + my $author_line = shift @line; + defined $author_line + or die "$ME:$.: unexpected EOF\n"; + $author_line =~ /^(\d+) (.*>)$/ + or die "$ME:$.: Invalid line " + . "(expected date/author/email):\n$author_line\n"; + + my $date_line = sprintf "%s $2\n", strftime ("%F", localtime ($1)); + # If this line would be the same as the previous date/name/email + # line, then arrange not to print it. + if ($date_line ne $prev_date_line) + { + $prev_date_line eq '' + or print "\n"; + print $date_line; + } + $prev_date_line = $date_line; + + # Omit "Signed-off-by..." lines. + @line = grep !/^Signed-off-by: .*>$/, @line; + + # If there were any lines + if (@line == 0) + { + warn "$ME: warning: empty commit message:\n $date_line\n"; + } + else + { + # Remove leading and trailing blank lines. + while ($line[0] =~ /^\s*$/) { shift @line; } + while ($line[$#line] =~ /^\s*$/) { pop @line; } + + # Prefix each non-empty line with a TAB. + @line = map { length $_ ? "\t$_" : '' } @line; + + print "\n", join ("\n", @line), "\n"; + } + + defined ($in = ) + or last; + $in ne "\n" + and die "$ME:$.: unexpected line:\n$in"; + } + + close PIPE + or die "$ME: error closing pipe from " . quoted_cmd (@cmd) . "\n"; + # FIXME-someday: include $PROCESS_STATUS in the diagnostic +} + +# Local Variables: +# indent-tabs-mode: nil +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "my $VERSION = '" +# time-stamp-format: "%:y-%02m-%02d %02H:%02M" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "'; # UTC" +# End: diff --git a/check-guile.in b/check-guile.in index 9ee2ea3f6..3162fa6fc 100644 --- a/check-guile.in +++ b/check-guile.in @@ -1,6 +1,6 @@ #! /bin/sh # Usage: check-guile [-i GUILE-INTERPRETER] [GUILE-TEST-ARGS] -# If `-i GUILE-INTERPRETER' is omitted, use ${top_builddir}/pre-inst-guile. +# If `-i GUILE-INTERPRETER' is omitted, use ${top_builddir}/meta/guile. # See ${top_srcdir}/test-suite/guile-test for documentation on GUILE-TEST-ARGS. # # Example invocations: @@ -21,7 +21,7 @@ if [ x"$1" = x-i ] ; then shift shift else - guile=${top_builddir}/pre-inst-guile + guile=${top_builddir}/meta/guile fi GUILE_LOAD_PATH=$TEST_SUITE_DIR @@ -41,7 +41,6 @@ if [ ! -f guile-procedures.txt ] ; then fi exec $guile \ - -l ${top_builddir}/libguile/stack-limit-calibration.scm \ -e main -s "$TEST_SUITE_DIR/guile-test" \ --test-suite "$TEST_SUITE_DIR/tests" \ --log-file check-guile.log "$@" diff --git a/configure.in b/configure.ac similarity index 94% rename from configure.in rename to configure.ac index 4061ac0af..697ffd1ce 100644 --- a/configure.in +++ b/configure.ac @@ -8,20 +8,20 @@ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, This file is part of GUILE -GUILE 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, or (at your -option) any later version. +GUILE is free software; you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License as published by the +Free Software Foundation; either version 3, or (at your option) any +later version. -GUILE 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. +GUILE is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +License for more details. -You should have received a copy of the GNU General Public License -along with GUILE; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -Boston, MA 02110-1301, USA. +You should have received a copy of the GNU Lesser General Public +License along with GUILE; see the file COPYING.LESSER. If not, write +to the Free Software Foundation, Inc., 51 Franklin Street, Fifth +Floor, Boston, MA 02110-1301, USA. ]]) @@ -159,6 +159,7 @@ AC_ARG_ENABLE([deprecated], if test "$enable_deprecated" = no; then SCM_I_GSC_ENABLE_DEPRECATED=0 + warn_default=no else if test "$enable_deprecated" = yes || test "$enable_deprecated" = ""; then warn_default=summary @@ -168,9 +169,9 @@ else warn_default=$enable_deprecated fi SCM_I_GSC_ENABLE_DEPRECATED=1 - AC_DEFINE_UNQUOTED(SCM_WARN_DEPRECATED_DEFAULT, "$warn_default", - [Define this to control the default warning level for deprecated features.]) fi +AC_DEFINE_UNQUOTED(SCM_WARN_DEPRECATED_DEFAULT, "$warn_default", +[Define this to control the default warning level for deprecated features.]) AC_ARG_ENABLE(elisp, [ --disable-elisp omit Emacs Lisp support],, @@ -620,6 +621,8 @@ AC_SUBST([SCM_I_GSC_HAVE_STRUCT_DIRENT64]) # Reasons for testing: # complex.h - new in C99 # fenv.h - available in C99, but not older systems +# machine/fpu.h - on Tru64 5.1b, the declaration of fesetround(3) is in +# this file instead of # process.h - mingw specific # langinfo.h, nl_types.h - SuS v2 # @@ -627,7 +630,7 @@ AC_CHECK_HEADERS([complex.h fenv.h io.h libc.h limits.h malloc.h memory.h proces regex.h rxposix.h rx/rxposix.h sys/dir.h sys/ioctl.h sys/select.h \ sys/time.h sys/timeb.h sys/times.h sys/stdtypes.h sys/types.h \ sys/utime.h time.h unistd.h utime.h pwd.h grp.h sys/utsname.h \ -direct.h langinfo.h nl_types.h]) +direct.h langinfo.h nl_types.h machine/fpu.h]) # "complex double" is new in C99, and "complex" is only a keyword if # is included @@ -733,10 +736,14 @@ AC_CHECK_FUNCS([DINFINITY DQNAN cexp chsize clog clog10 ctermid fesetround ftime # sethostname - the function itself check because it's not in mingw, # the DECL is checked because Solaris 10 doens't have in any header # xlocale.h - needed on Darwin for the `locale_t' API +# hstrerror - on Tru64 5.1b the symbol is available in libc but the +# declaration isn't anywhere. +# cuserid - on Tru64 5.1b the declaration is documented to be available +# only with `_XOPEN_SOURCE' or some such. # AC_CHECK_HEADERS(crypt.h netdb.h pthread.h sys/param.h sys/resource.h sys/file.h xlocale.h) AC_CHECK_FUNCS(chroot flock getlogin cuserid getpriority setpriority getpass sethostname gethostname) -AC_CHECK_DECLS([sethostname]) +AC_CHECK_DECLS([sethostname, hstrerror, cuserid]) # crypt() may or may not be available, for instance in some countries there # are restrictions on cryptography. @@ -820,14 +827,13 @@ fi dnl GMP tests -AC_CHECK_LIB([gmp], [__gmpz_init], , - [AC_MSG_ERROR([GNU MP not found, see README])]) - -# mpz_import is a macro so we need to include -AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], - [[mpz_import (0, 0, 0, 0, 0, 0, 0); ]])], +AC_LIB_HAVE_LINKFLAGS(gmp, [], - [AC_MSG_ERROR([At least GNU MP 4.1 is required, see README])]) + [#include ], + [mpz_import (0, 0, 0, 0, 0, 0, 0);], + AC_MSG_ERROR([GNU MP 4.1 or greater not found, see README])) + +dnl GNU libunistring is checked for by Gnulib's `libunistring' module. dnl i18n tests #AC_CHECK_HEADERS([libintl.h]) @@ -883,6 +889,8 @@ if test -n "$have_sys_un_h" ; then [Define if the system supports Unix-domain (file-domain) sockets.]) fi +AC_CHECK_FUNCS(getrlimit setrlimit) + AC_CHECK_FUNCS(socketpair getgroups setgroups setpwent pause tzset) AC_CHECK_FUNCS(sethostent gethostent endhostent dnl @@ -1037,18 +1045,6 @@ if test $guile_cv_localtime_cache = yes; then AC_DEFINE(LOCALTIME_CACHE, 1, [Define if localtime caches the TZ setting.]) fi -dnl Test whether system calls are restartable by default on the -dnl current system. If they are not, we put a loop around every system -dnl call to check for EINTR (see SCM_SYSCALL) and do not attempt to -dnl change from the default behaviour. On the other hand, if signals -dnl are restartable then the loop is not installed and when libguile -dnl initialises it also resets the behaviour of each signal to cause a -dnl restart (in case a different runtime had a different default -dnl behaviour for some reason: e.g., different versions of linux seem -dnl to behave differently.) - -AC_SYS_RESTARTABLE_SYSCALLS - if test "$enable_regex" = yes; then if test "$ac_cv_header_regex_h" = yes || test "$ac_cv_header_rxposix_h" = yes || @@ -1260,11 +1256,12 @@ case "$with_threads" in build_pthread_support="yes" - ACX_PTHREAD(CC="$PTHREAD_CC" - LIBS="$PTHREAD_LIBS $LIBS" - SCM_I_GSC_USE_PTHREAD_THREADS=1 - with_threads="pthreads", - with_threads="null") + ACX_PTHREAD([CC="$PTHREAD_CC" + LIBS="$PTHREAD_LIBS $LIBS" + SCM_I_GSC_USE_PTHREAD_THREADS=1 + with_threads="pthreads"], + [with_threads="null" + build_pthread_support="no"]) old_CFLAGS="$CFLAGS" CFLAGS="$PTHREAD_CFLAGS $CFLAGS" @@ -1551,37 +1548,24 @@ AC_CONFIG_FILES([ doc/tutorial/Makefile emacs/Makefile examples/Makefile - examples/box-dynamic-module/Makefile - examples/box-dynamic/Makefile - examples/box-module/Makefile - examples/box/Makefile - examples/modules/Makefile - examples/safe/Makefile - examples/scripts/Makefile - guile-config/Makefile lang/Makefile libguile/Makefile - scripts/Makefile srfi/Makefile test-suite/Makefile test-suite/standalone/Makefile + meta/Makefile module/Makefile - module/ice-9/Makefile - module/ice-9/debugger/Makefile - module/ice-9/debugging/Makefile - module/srfi/Makefile - module/oop/Makefile - module/oop/goops/Makefile testsuite/Makefile ]) -AC_CONFIG_FILES([guile-1.8.pc]) +AC_CONFIG_FILES([meta/guile-2.0.pc]) +AC_CONFIG_FILES([meta/guile-2.0-uninstalled.pc]) AC_CONFIG_FILES([check-guile], [chmod +x check-guile]) AC_CONFIG_FILES([benchmark-guile], [chmod +x benchmark-guile]) -AC_CONFIG_FILES([guile-tools], [chmod +x guile-tools]) -AC_CONFIG_FILES([pre-inst-guile], [chmod +x pre-inst-guile]) -AC_CONFIG_FILES([pre-inst-guile-env], [chmod +x pre-inst-guile-env]) -AC_CONFIG_FILES([gdb-pre-inst-guile], [chmod +x gdb-pre-inst-guile]) +AC_CONFIG_FILES([meta/guile], [chmod +x meta/guile]) +AC_CONFIG_FILES([meta/uninstalled-env], [chmod +x meta/uninstalled-env]) +AC_CONFIG_FILES([meta/gdb-uninstalled-guile], [chmod +x meta/gdb-uninstalled-guile]) +AC_CONFIG_FILES([meta/guile-tools], [chmod +x meta/guile-tools]) AC_CONFIG_FILES([libguile/guile-snarf], [chmod +x libguile/guile-snarf]) AC_CONFIG_FILES([libguile/guile-doc-snarf], diff --git a/doc/Makefile.am b/doc/Makefile.am index f4e0718d6..0a6b14ed5 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -1,23 +1,23 @@ ## Process this file with Automake to create Makefile.in ## -## Copyright (C) 1998, 2002, 2006, 2008 Free Software Foundation, Inc. +## Copyright (C) 1998, 2002, 2006, 2008, 2009 Free Software Foundation, Inc. ## ## This file is part of GUILE. ## -## GUILE 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, or +## GUILE is free software; you can redistribute it and/or modify it +## under the terms of the GNU Lesser General Public License as +## published by the Free Software Foundation; either version 3, or ## (at your option) any later version. ## ## GUILE 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. +## GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU General Public -## License along with GUILE; see the file COPYING. If not, write -## to the Free Software Foundation, Inc., 51 Franklin Street, Fifth -## Floor, Boston, MA 02110-1301 USA +## You should have received a copy of the GNU Lesser General Public +## License along with GUILE; see the file COPYING.LESSER. If not, +## write to the Free Software Foundation, Inc., 51 Franklin Street, +## Fifth Floor, Boston, MA 02110-1301 USA AUTOMAKE_OPTIONS = gnu @@ -43,5 +43,3 @@ include $(top_srcdir)/am/maintainer-dirs guile-api.alist: guile-api.alist-FORCE ( cd $(top_builddir) ; $(mscripts)/update-guile-api.alist ) guile-api.alist-FORCE: - -info_TEXINFOS = guile-vm.texi diff --git a/doc/example-smob/image-type.c b/doc/example-smob/image-type.c index 68ecded9d..8dd998a50 100644 --- a/doc/example-smob/image-type.c +++ b/doc/example-smob/image-type.c @@ -2,20 +2,20 @@ * * Copyright (C) 1998, 2000, 2004, 2006 Free Software Foundation, Inc. * - * 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 2, or (at your option) - * any later version. + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3, 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. + * 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 + * Lesser General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this software; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA + * You should have received a copy of the GNU Lesser General Public + * License along with this software; see the file COPYING.LESSER. If + * not, write to the Free Software Foundation, Inc., 51 Franklin + * Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include diff --git a/doc/example-smob/myguile.c b/doc/example-smob/myguile.c index 9df3cf31b..30200dd03 100644 --- a/doc/example-smob/myguile.c +++ b/doc/example-smob/myguile.c @@ -2,20 +2,20 @@ * * Copyright (C) 1998, 2006 Free Software Foundation, Inc. * - * 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 2, or (at your option) - * any later version. + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3, 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. + * 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 + * Lesser General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this software; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA + * You should have received a copy of the GNU Lesser General Public + * License along with this software; see the file COPYING.LESSER. If + * not, write to the Free Software Foundation, Inc., 51 Franklin + * Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include diff --git a/doc/goops/Makefile.am b/doc/goops/Makefile.am index 03794c4de..49bfb29b9 100644 --- a/doc/goops/Makefile.am +++ b/doc/goops/Makefile.am @@ -4,20 +4,20 @@ ## ## This file is part of GUILE. ## -## GUILE 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, or +## GUILE is free software; you can redistribute it and/or modify it +## under the terms of the GNU Lesser General Public License as +## published by the Free Software Foundation; either version 3, or ## (at your option) any later version. -## +## ## GUILE 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 GUILE; see the file COPYING. If not, write -## to the Free Software Foundation, Inc., 51 Franklin Street, Fifth -## Floor, Boston, MA 02110-1301 USA +## GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with GUILE; see the file COPYING.LESSER. If not, +## write to the Free Software Foundation, Inc., 51 Franklin Street, +## Fifth Floor, Boston, MA 02110-1301 USA AUTOMAKE_OPTIONS = gnu diff --git a/doc/groupings.alist b/doc/groupings.alist index ed5bb1fca..a1748196f 100644 --- a/doc/groupings.alist +++ b/doc/groupings.alist @@ -3,19 +3,19 @@ ;; Copyright (C) 2002, 2006 Free Software Foundation, Inc. ;; ;; 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 2, or +;; modify it under the terms of the GNU Lesser General Public License +;; as published by the Free Software Foundation; either version 3, 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 +;; +;; 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 software; see the file COPYING. If not, write to -;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;; Boston, MA 02110-1301 USA +;; Lesser General Public License for more details. +;; +;; You should have received a copy of the GNU Lesser General Public +;; License along with this software; see the file COPYING.LESSER. If +;; not, write to the Free Software Foundation, Inc., 51 Franklin +;; Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Commentary: diff --git a/doc/guile-vm.texi b/doc/guile-vm.texi deleted file mode 100644 index 927c09e88..000000000 --- a/doc/guile-vm.texi +++ /dev/null @@ -1,1042 +0,0 @@ -\input texinfo @c -*-texinfo-*- -@c %**start of header -@setfilename guile-vm.info -@settitle Guile VM Specification -@footnotestyle end -@setchapternewpage odd -@c %**end of header - -@set EDITION 0.6 -@set VERSION 0.6 -@set UPDATED 2005-04-26 - -@c Macro for instruction definitions. -@macro insn{} -Instruction -@end macro - -@c For Scheme procedure definitions. -@macro scmproc{} -Scheme Procedure -@end macro - -@c Scheme records. -@macro scmrec{} -Record -@end macro - -@ifinfo -@dircategory Scheme Programming -@direntry -* Guile VM: (guile-vm). Guile's Virtual Machine. -@end direntry - -This file documents Guile VM. - -Copyright @copyright{} 2000 Keisuke Nishida -Copyright @copyright{} 2005 Ludovic Court`es - -Permission is granted to make and distribute verbatim copies of this -manual provided the copyright notice and this permission notice are -preserved on all copies. - -@ignore -Permission is granted to process this file through TeX and print the -results, provided the printed document carries a copying permission -notice identical to this one except for the removal of this paragraph -(this paragraph not being relevant to the printed manual). - -@end ignore -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided that the -entire resulting derived work is distributed under the terms of a -permission notice identical to this one. - -Permission is granted to copy and distribute translations of this manual -into another language, under the above conditions for modified versions, -except that this permission notice may be stated in a translation -approved by the Free Software Foundation. -@end ifinfo - -@titlepage -@title Guile VM Specification -@subtitle for Guile VM @value{VERSION} -@author Keisuke Nishida - -@page -@vskip 0pt plus 1filll -Edition @value{EDITION} @* -Updated for Guile VM @value{VERSION} @* -@value{UPDATED} @* - -Copyright @copyright{} 2000 Keisuke Nishida -Copyright @copyright{} 2005 Ludovic Court`es - -Permission is granted to make and distribute verbatim copies of this -manual provided the copyright notice and this permission notice are -preserved on all copies. - -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided that the -entire resulting derived work is distributed under the terms of a -permission notice identical to this one. - -Permission is granted to copy and distribute translations of this manual -into another language, under the above conditions for modified versions, -except that this permission notice may be stated in a translation -approved by the Free Software Foundation. -@end titlepage - -@contents - -@c ********************************************************************* -@node Top, Introduction, (dir), (dir) -@top Guile VM Specification - -This document would like to correspond to Guile VM @value{VERSION}. -However, be warned that important parts still correspond to version -0.0 and are not valid anymore. - -@menu -* Introduction:: -* Variable Management:: -* Instruction Set:: -* The Compiler:: -* Concept Index:: -* Function and Instruction Index:: -* Command and Variable Index:: - -@detailmenu - --- The Detailed Node Listing --- - -Instruction Set - -* Environment Control Instructions:: -* Branch Instructions:: -* Subprogram Control Instructions:: -* Data Control Instructions:: - -The Compiler - -* Overview:: -* The Language Front-Ends:: -* GHIL:: -* Compiling Scheme Code:: -* GLIL:: -* The Assembler:: - -@end detailmenu -@end menu - -@c ********************************************************************* -@node Introduction, Variable Management, Top, Top -@chapter What is Guile VM? - -A Guile VM has a set of registers and its own stack memory. Guile may -have more than one VM's. Each VM may execute at most one program at a -time. Guile VM is a CISC system so designed as to execute Scheme and -other languages efficiently. - -@unnumberedsubsec Registers - -@itemize -@item pc - Program counter ;; ip (instruction poiner) is better? -@item sp - Stack pointer -@item bp - Base pointer -@item ac - Accumulator -@end itemize - -@unnumberedsubsec Engine - -A VM may have one of three engines: reckless, regular, or debugging. -Reckless engine is fastest but dangerous. Regular engine is normally -fail-safe and reasonably fast. Debugging engine is safest and -functional but very slow. - -@unnumberedsubsec Memory - -Stack is the only memory that each VM owns. The other memory is shared -memory that is shared among every VM and other part of Guile. - -@unnumberedsubsec Program - -A VM program consists of a bytecode that is executed and an environment -in which execution is done. Each program is allocated in the shared -memory and may be executed by any VM. A program may call other programs -within a VM. - -@unnumberedsubsec Instruction - -Guile VM has dozens of system instructions and (possibly) hundreds of -functional instructions. Some Scheme procedures such as cons and car -are implemented as VM's builtin functions, which are very efficient. -Other procedures defined outside of the VM are also considered as VM's -functional features, since they do not change the state of VM. -Procedures defined within the VM are called subprograms. - -Most instructions deal with the accumulator (ac). The VM stores all -results from functions in ac, instead of pushing them into the stack. -I'm not sure whether this is a good thing or not. - -@node Variable Management, Instruction Set, Introduction, Top -@chapter Variable Management - -FIXME: This chapter needs to be reviewed so that it matches reality. -A more up-to-date description of the mechanisms described in this -section is given in @ref{Instruction Set}. - -A program may have access to local variables, external variables, and -top-level variables. - -@section Local/external variables - -A stack is logically divided into several blocks during execution. A -"block" is such a unit that maintains local variables and dynamic chain. -A "frame" is an upper level unit that maintains subprogram calls. - -@example - Stack - dynamic | | | | - chain +==========+ - = - | |local vars| | | - `-|block data| | block | - /|frame data| | | - | +----------+ - | - | |local vars| | | frame - `-|block data| | | - /+----------+ - | - | |local vars| | | - `-|block data| | | - /+==========+ - = - | |local vars| | | - `-|block data| | | - /|frame data| | | - | +----------+ - | - | | | | | -@end example - -The first block of each frame may look like this: - -@example - Address Data - ------- ---- - xxx0028 Local variable 2 - xxx0024 Local variable 1 - bp ->xxx0020 Local variable 0 - xxx001c Local link (block data) - xxx0018 External link (block data) - xxx0014 Stack pointer (block data) - xxx0010 Return address (frame data) - xxx000c Parent program (frame data) -@end example - -The base pointer (bp) always points to the lowest address of local -variables of the recent block. Local variables are referred as "bp[n]". -The local link field has a pointer to the dynamic parent of the block. -The parent's variables are referred as "bp[-1][n]", and grandparent's -are "bp[-1][-1][n]". Thus, any local variable is represented by its -depth and offset from the current bp. - -A variable may be "external", which is allocated in the shared memory. -The external link field of a block has a pointer to such a variable set, -which I call "fragment" (what should I call?). A fragment has a set of -variables and its own chain. - -@example - local external - chain| | chain - | +-----+ .--------, | - `-|block|--+->|external|-' - /+-----+ | `--------'\, - `-|block|--' | - /+-----+ .--------, | - `-|block|---->|external|-' - +-----+ `--------' - | | -@end example - -An external variable is referred as "bp[-2]->variables[n]" or -"bp[-2]->link->...->variables[n]". This is also represented by a pair -of depth and offset. At any point of execution, the value of bp -determines the current local link and external link, and thus the -current environment of a program. - -Other data fields are described later. - -@section Top-level variables - -Guile VM uses the same top-level variables as the regular Guile. A -program may have direct access to vcells. Currently this is done by -calling scm_intern0, but a program is possible to have any top-level -environment defined by the current module. - -@section Scheme and VM variable - -Let's think about the following Scheme code as an example: - -@example - (define (foo a) - (lambda (b) (list foo a b))) -@end example - -In the lambda expression, "foo" is a top-level variable, "a" is an -external variable, and "b" is a local variable. - -When a VM executes foo, it allocates a block for "a". Since "a" may be -externally referred from the closure, the VM creates a fragment with a -copy of "a" in it. When the VM evaluates the lambda expression, it -creates a subprogram (closure), associating the fragment with the -subprogram as its external environment. When the closure is executed, -its environment will look like this: - -@example - block Top-level: foo - +-------------+ - |local var: b | fragment - +-------------+ .-----------, - |external link|---->|variable: a| - +-------------+ `-----------' -@end example - -The fragment remains as long as the closure exists. - -@section Addressing mode - -Guile VM has five addressing modes: - -@itemize -@item Real address -@item Local position -@item External position -@item Top-level location -@item Constant object -@end itemize - -Real address points to the address in the real program and is only used -with the program counter (pc). - -Local position and external position are represented as a pair of depth -and offset from bp, as described above. These are base relative -addresses, and the real address may vary during execution. - -Top-level location is represented as a Guile's vcell. This location is -determined at loading time, so the use of this address is efficient. - -Constant object is not an address but gives an instruction an Scheme -object directly. - -[ We'll also need dynamic scope addressing to support Emacs Lisp? ] - - -Overall procedure: - -@enumerate -@item A source program is compiled into a bytecode. -@item A bytecode is given an environment and becomes a program. -@item A VM starts execution, creating a frame for it. -@item Whenever a program calls a subprogram, a new frame is created for it. -@item When a program finishes execution, it returns a value, and the VM - continues execution of the parent program. -@item When all programs terminated, the VM returns the final value and stops. -@end enumerate - - -@node Instruction Set, The Compiler, Variable Management, Top -@chapter Instruction Set - -The Guile VM instruction set is roughly divided two groups: system -instructions and functional instructions. System instructions control -the execution of programs, while functional instructions provide many -useful calculations. - -@menu -* Environment Control Instructions:: -* Branch Instructions:: -* Subprogram Control Instructions:: -* Data Control Instructions:: -@end menu - -@node Environment Control Instructions, Branch Instructions, Instruction Set, Instruction Set -@section Environment Control Instructions - -@deffn @insn{} link binding-name -Look up @var{binding-name} (a string) in the current environment and -push the corresponding variable object onto the stack. If -@var{binding-name} is not bound yet, then create a new binding and -push its variable object. -@end deffn - -@deffn @insn{} variable-ref -Dereference the variable object which is on top of the stack and -replace it by the value of the variable it represents. -@end deffn - -@deffn @insn{} variable-set -Set the value of the variable on top of the stack (at @code{sp[0]}) to -the object located immediately before (at @code{sp[-1]}). -@end deffn - -As an example, let us look at what a simple function call looks like: - -@example -(+ 2 3) -@end example - -This call yields the following sequence of instructions: - -@example -(link "+") ;; lookup binding "+" -(variable-ref) ;; dereference it -(make-int8 2) ;; push immediate value `2' -(make-int8 3) ;; push immediate value `3' -(tail-call 2) ;; call the proc at sp[-3] with two args -@end example - -@deffn @insn{} local-ref offset -Push onto the stack the value of the local variable located at -@var{offset} within the current stack frame. -@end deffn - -@deffn @insn{} local-set offset -Pop the Scheme object located on top of the stack and make it the new -value of the local variable located at @var{offset} within the current -stack frame. -@end deffn - -@deffn @insn{} external-ref offset -Push the value of the closure variable located at position -@var{offset} within the program's list of external variables. -@end deffn - -@deffn @insn{} external-set offset -Pop the Scheme object located on top of the stack and make it the new -value of the closure variable located at @var{offset} within the -program's list of external variables. -@end deffn - -@deffn @insn{} make-closure -Pop the program object from the stack and assign it the current -closure variable list as its closure. Push the result program -object. -@end deffn - -Let's illustrate this: - -@example -(let ((x 2)) - (lambda () - (let ((x++ (+ 1 x))) - (set! x x++) - x++))) -@end example - -The resulting program has one external (closure) variable, i.e. its -@var{nexts} is set to 1 (@pxref{Subprogram Control Instructions}). -This yields the following code: - -@example - ;; the traditional program prologue with NLOCS = 0 and NEXTS = 1 - - 0 (make-int8 2) - 2 (external-set 0) - 4 (make-int8 4) - 6 (link "+") ;; lookup `+' - 9 (vector 1) ;; create the external variable vector for - ;; later use by `object-ref' and `object-set' - ... - 40 (load-program ##34#) - 59 (make-closure) ;; assign the current closure to the program - ;; just pushed by `load-program' - 60 (return) -@end example - -The program loaded here by @var{load-program} contains the following -sequence of instructions: - -@example - 0 (object-ref 0) ;; push the variable for `+' - 2 (variable-ref) ;; dereference `+' - 3 (make-int8:1) ;; push 1 - 4 (external-ref 0) ;; push the value of `x' - 6 (call 2) ;; call `+' and push the result - 8 (local-set 0) ;; make it the new value of `x++' - 10 (local-ref 0) ;; push the value of `x++' - 12 (external-set 0) ;; make it the new value of `x' - 14 (local-ref 0) ;; push the value of `x++' - 16 (return) ;; return it -@end example - -At this point, you should know pretty much everything about the three -types of variables a program may need to access. - - -@node Branch Instructions, Subprogram Control Instructions, Environment Control Instructions, Instruction Set -@section Branch Instructions - -All the conditional branch instructions described below work in the -same way: - -@itemize -@item They take the Scheme object located on the stack and use it as -the branch condition; -@item If the condition if false, then program execution continues with -the next instruction; -@item If the condition is true, then the instruction pointer is -increased by the offset passed as an argument to the branch -instruction; -@item Finally, when the instruction finished, the condition object is -removed from the stack. -@end itemize - -Note that the offset passed to the instruction is encoded on two 8-bit -integers which are then combined by the VM as one 16-bit integer. - -@deffn @insn{} br offset -Jump to @var{offset}. -@end deffn - -@deffn @insn{} br-if offset -Jump to @var{offset} if the condition on the stack is not false. -@end deffn - -@deffn @insn{} br-if-not offset -Jump to @var{offset} if the condition on the stack is false. -@end deffn - -@deffn @insn{} br-if-eq offset -Jump to @var{offset} if the two objects located on the stack are -equal in the sense of @var{eq?}. Note that, for this instruction, the -stack pointer is decremented by two Scheme objects instead of only -one. -@end deffn - -@deffn @insn{} br-if-not-eq offset -Same as @var{br-if-eq} for non-equal objects. -@end deffn - -@deffn @insn{} br-if-null offset -Jump to @var{offset} if the object on the stack is @code{'()}. -@end deffn - -@deffn @insn{} br-if-not-null offset -Jump to @var{offset} if the object on the stack is not @code{'()}. -@end deffn - - -@node Subprogram Control Instructions, Data Control Instructions, Branch Instructions, Instruction Set -@section Subprogram Control Instructions - -Programs (read: ``compiled procedure'') may refer to external -bindings, like variables or functions defined outside the program -itself, in the environment in which it will evaluate at run-time. In -a sense, a program's environment and its bindings are an implicit -parameter of every program. - -@cindex object table -In order to handle such bindings, each program has an @dfn{object -table} associated to it. This table (actually a Scheme vector) -contains all constant objects referenced by the program. The object -table of a program is initialized right before a program is loaded -with @var{load-program}. - -Variable objects are one such type of constant object: when a global -binding is defined, a variable object is associated to it and that -object will remain constant over time, even if the value bound to it -changes. Therefore, external bindings only need to be looked up once -when the program is loaded. References to the corresponding external -variables from within the program are then performed via the -@var{object-ref} instruction and are almost as fast as local variable -references. - -Let us consider the following program (procedure) which references -external bindings @code{frob} and @var{%magic}: - -@example -(lambda (x) - (frob x %magic)) -@end example - -This yields the following assembly code: - -@example -(make-int8 64) ;; number of args, vars, etc. (see below) -(link "frob") -(link "%magic") -(vector 2) ;; object table (external bindings) -... -(load-program #u8(20 0 23 21 0 20 1 23 36 2)) -(return) -@end example - -All the instructions occurring before @var{load-program} (some were -omitted for simplicity) form a @dfn{prologue} which, among other -things, pushed an object table (a vector) that contains the variable -objects for the variables bound to @var{frob} and @var{%magic}. This -vector and other data pushed onto the stack are then popped by the -@var{load-program} instruction. - -Besides, the @var{load-program} instruction takes one explicit -argument which is the bytecode of the program itself. Disassembled, -this bytecode looks like: - -@example -(object-ref 0) ;; push the variable object of `frob' -(variable-ref) ;; dereference it -(local-ref 0) ;; push the value of `x' -(object-ref 1) ;; push the variable object of `%magic' -(variable-ref) ;; dereference it -(tail-call 2) ;; call `frob' with two parameters -@end example - -This clearly shows that there is little difference between references -to local variables and references to externally bound variables since -lookup of externally bound variables if performed only once before the -program is run. - -@deffn @insn{} load-program bytecode -Load the program whose bytecode is @var{bytecode} (a u8vector), pop -its meta-information from the stack, and push a corresponding program -object onto the stack. The program's meta-information may consist of -(in the order in which it should be pushed onto the stack): - -@itemize -@item optionally, a pair representing meta-data (see the -@var{program-meta} procedure); [FIXME: explain their meaning] -@item optionally, a vector which is the program's object table (a -program that does not reference external bindings does not need an -object table); -@item either one immediate integer or four immediate integers -representing respectively the number of arguments taken by the -function (@var{nargs}), the number of @dfn{rest arguments} -(@var{nrest}, 0 or 1), the number of local variables (@var{nlocs}) and -the number of external variables (@var{nexts}) (@pxref{Environment -Control Instructions}). -@end itemize - -@end deffn - -@deffn @insn{} object-ref offset -Push the variable object for the external variable located at -@var{offset} within the program's object table. -@end deffn - -@deffn @insn{} return -Free the program's frame. -@end deffn - -@deffn @insn{} call nargs -Call the procedure, continuation or program located at -@code{sp[-nargs]} with the @var{nargs} arguments located from -@code{sp[0]} to @code{sp[-nargs + 1]}. The -procedure/continuation/program and its arguments are dropped from the -stack and the result is pushed. When calling a program, the -@code{call} instruction reserves room for its local variables on the -stack, and initializes its list of closure variables and its vector of -externally bound variables. -@end deffn - -@deffn @insn{} tail-call nargs -Same as @code{call} except that, for tail-recursive calls to a -program, the current stack frame is re-used, as required by RnRS. -This instruction is otherwise similar to @code{call}. -@end deffn - - -@node Data Control Instructions, , Subprogram Control Instructions, Instruction Set -@section Data Control Instructions - -@deffn @insn{} make-int8 value -Push @var{value}, an 8-bit integer, onto the stack. -@end deffn - -@deffn @insn{} make-int8:0 -Push the immediate value @code{0} onto the stack. -@end deffn - -@deffn @insn{} make-int8:1 -Push the immediate value @code{1} onto the stack. -@end deffn - -@deffn @insn{} make-false -Push @code{#f} onto the stack. -@end deffn - -@deffn @insn{} make-true -Push @code{#t} onto the stack. -@end deffn - -@itemize -@item %push -@item %pushi -@item %pushl, %pushl:0:0, %pushl:0:1, %pushl:0:2, %pushl:0:3 -@item %pushe, %pushe:0:0, %pushe:0:1, %pushe:0:2, %pushe:0:3 -@item %pusht -@end itemize - -@itemize -@item %loadi -@item %loadl, %loadl:0:0, %loadl:0:1, %loadl:0:2, %loadl:0:3 -@item %loade, %loade:0:0, %loade:0:1, %loade:0:2, %loade:0:3 -@item %loadt -@end itemize - -@itemize -@item %savei -@item %savel, %savel:0:0, %savel:0:1, %savel:0:2, %savel:0:3 -@item %savee, %savee:0:0, %savee:0:1, %savee:0:2, %savee:0:3 -@item %savet -@end itemize - -@section Flow control instructions - -@itemize -@item %br-if -@item %br-if-not -@item %jump -@end itemize - -@section Function call instructions - -@itemize -@item %func, %func0, %func1, %func2 -@end itemize - -@section Scheme built-in functions - -@itemize -@item cons -@item car -@item cdr -@end itemize - -@section Mathematical buitin functions - -@itemize -@item 1+ -@item 1- -@item add, add2 -@item sub, sub2, minus -@item mul2 -@item div2 -@item lt2 -@item gt2 -@item le2 -@item ge2 -@item num-eq2 -@end itemize - - - -@node The Compiler, Concept Index, Instruction Set, Top -@chapter The Compiler - -This section describes Guile-VM's compiler and the compilation process -to produce bytecode executable by the VM itself (@pxref{Instruction -Set}). - -@menu -* Overview:: -* The Language Front-Ends:: -* GHIL:: -* Compiling Scheme Code:: -* GLIL:: -* The Assembler:: -@end menu - -@node Overview, The Language Front-Ends, The Compiler, The Compiler -@section Overview - -Compilation in Guile-VM is a three-stage process: - -@cindex intermediate language -@cindex assembler -@cindex compiler -@cindex GHIL -@cindex GLIL -@cindex bytecode - -@enumerate -@item the source programming language (e.g. R5RS Scheme) is read and -translated into GHIL, @dfn{Guile's High-Level Intermediate Language}; -@item GHIL code is then translated into a lower-level intermediate -language call GLIL, @dfn{Guile's Low-Level Intermediate Language}; -@item finally, GLIL is @dfn{assembled} into the VM's assembly language -(@pxref{Instruction Set}) and bytecode. -@end enumerate - -The use of two separate intermediate languages eases the -implementation of front-ends since the gap between high-level -languages like Scheme and GHIL is relatively small. - -@vindex guilec -From an end-user viewpoint, compiling a Guile program into bytecode -can be done either by using the @command{guilec} command-line tool, or -by using the @code{compile-file} procedure exported by the -@code{(system base compile)} module. - -@deffn @scmproc{} compile-file file . opts -Compile Scheme source code from file @var{file} using compilation -options @var{opts}. The resulting file, a Guile object file, will be -name according the application of the @code{compiled-file-name} -procedure to @var{file}. The possible values for @var{opts} are the -same as for the @code{compile-in} procedure (see below, @pxref{The Language -Front-Ends}). -@end deffn - -@deffn @scmproc{} compiled-file-name file -Given source file name @var{file} (a string), return a string that -denotes the name of the Guile object file corresponding to -@var{file}. By default, the file name returned is @var{file} minus -its extension and plus the @code{.go} file extension. -@end deffn - -@cindex self-hosting -It is worth noting, as you might have already guessed, that Guile-VM's -compiler is written in Guile Scheme and is @dfn{self-hosted}: it can -compile itself. - -@node The Language Front-Ends, GHIL, Overview, The Compiler -@section The Language Front-Ends - -Guile-VM comes with a number of @dfn{language front-ends}, that is, -code that can read a given high-level programming language like R5RS -Scheme, and translate it into a lower-level representation suitable to -the compiler. - -Each language front-end provides a @dfn{specification} and a -@dfn{translator} to GHIL. Both of them come in the @code{language} -module hierarchy. As an example, the front-end for Scheme is located -in the @code{(language scheme spec)} and @code{(language scheme -translate)} modules. Language front-ends can then be retrieved using -the @code{lookup-language} procedure of the @code{(system base -language)} module. - -@deftp @scmrec{} name title version reader printer read-file expander translator evaluator environment -Denotes a language front-end specification a various methods used by -the compiler to handle source written in that language. Of particular -interest is the @code{translator} slot (@pxref{GHIL}). -@end deftp - -@deffn @scmproc{} lookup-language lang -Look for a language front-end named @var{lang}, a symbol (e.g, -@code{scheme}), and return the @code{} record describing it -if found. If @var{lang} does not denote a language front-end, an -error is raised. Note that this procedure assumes that language -@var{lang} exists if there exist a @code{(language @var{lang} spec)} -module. -@end deffn - -The @code{(system base compile)} module defines a procedure similar to -@code{compile-file} but that is not limited to the Scheme language: - -@deffn @scmproc{} compile-in expr env lang . opts -Compile expression @var{expr}, which is written in language @var{lang} -(a @code{} object), using compilation options @var{opts}, -and return bytecode as produced by the assembler (@pxref{The -Assembler}). - -Options @var{opts} may contain the following keywords: - -@table @code -@item :e -compilation will stop after the code expansion phase. -@item :t -compilation will stop after the code translation phase, i.e. after -code in the source language @var{lang} has been translated into GHIL -(@pxref{GHIL}). -@item :c -compilation will stop after the compilation phase and before the -assembly phase, i.e. once GHIL has been translated into GLIL -(@pxref{GLIL}). -@end table - -Additionally, @var{opts} may contain any option understood by the -GHIL-to-GLIL compiler described in @xref{GLIL}. -@end deffn - - -@node GHIL, Compiling Scheme Code, The Language Front-Ends, The Compiler -@section Guile's High-Level Intermediate Language - -GHIL has constructs almost equivalent to those found in Scheme. -However, unlike Scheme, it is meant to be read only by the compiler -itself. Therefore, a sequence of GHIL code is only a sequence of GHIL -@emph{objects} (records), as opposed to symbols, each of which -represents a particular language feature. These records are all -defined in the @code{(system il ghil)} module and are named -@code{}. - -Each GHIL record has at least two fields: one containing the -environment (Guile module) in which it is considered, and one -containing its location [FIXME: currently seems to be unused]. Below -is a list of the main GHIL object types and their fields: - -@example -;; Objects -( env loc) -( env loc obj) -( env loc exp) -( env loc exp) -( env loc exp) -;; Variables -( env loc var) -( env loc var val) -( env loc var val) -;; Controls -( env loc test then else) -( env loc exps) -( env loc exps) -( env loc exps) -( env loc vars vals body) -( env loc vars rest body) -( env loc proc args) -( env loc inline args) -@end example - -As can be seen from this examples, the constructs in GHIL are pretty -close to the fundamental primitives of Scheme. - -It is the role of front-end language translators (@pxref{The Language -Front-Ends}) to produce a sequence of GHIL objects from the -human-readable, source programming language. The next section -describes the translator for the Scheme language. - -@node Compiling Scheme Code, GLIL, GHIL, The Compiler -@section Compiling Scheme Code - -The language object for Scheme, as returned by @code{(lookup-language -'scheme)} (@pxref{The Language Front-Ends}), defines a translator -procedure that returns a sequence of GHIL objects given Scheme code. -Before actually performing this operation, the Scheme translator -expands macros in the original source code. - -The macros that may be expanded can come from different sources: - -@itemize -@item core Guile macros, such as @code{false-if-exception}; -@item macros defined in modules used by the module being compiled, -e.g., @code{receive} in @code{(ice-9 receive)}; -@item macros defined within the module being compiled. -@end itemize - -@cindex macro -@cindex syntax transformer -@findex define-macro -@findex defmacro -The main complexity in handling macros at compilation time is that -Guile's macros are first-class objects. For instance, when using -@code{define-macro}, one actually defines a @emph{procedure} that -returns code; of course, unlike a ``regular'' procedure, it is -executed when an S-exp is @dfn{memoized} by the evaluator, i.e., -before the actual evaluation takes place. Worse, it is possible to -turn a procedure into a macro, or @dfn{syntax transformer}, thus -removing, to some extent, the boundary between the macro expansion and -evaluation phases, @inforef{Internal Macros, , guile}. - -[FIXME: explain limitations, etc.] - - -@node GLIL, The Assembler, Compiling Scheme Code, The Compiler -@section Guile's Low-Level Intermediate Language - -A GHIL instruction sequence can be compiled into GLIL using the -@code{compile} procedure exported by the @code{(system il compile)} -module. During this translation process, various optimizations may -also be performed. - -The module @code{(system il glil)} defines record types representing -various low-level abstractions. Compared to GHIL, the flow control -primitives in GLIL are much more low-level: only @code{}, -@code{} and @code{} are available, no -@code{lambda}, @code{if}, etc. - - -@deffn @scmproc{} compile ghil environment . opts -Compile @var{ghil}, a GHIL instruction sequence, within -environment/module @var{environment}, and return the resulting GLIL -instruction sequence. The option list @var{opts} may be either the -empty list or a list containing the @code{:O} keyword in which case -@code{compile} will first go through an optimization stage of -@var{ghil}. - -Note that the @code{:O} option may be passed at a higher-level to the -@code{compile-file} and @code{compile-in} procedures (@pxref{The -Language Front-Ends}). -@end deffn - -@deffn @scmproc{} pprint-glil glil . port -Print @var{glil}, a GLIL sequence instructions, in a human-readable -form. If @var{port} is passed, it will be used as the output port. -@end deffn - - -Let's consider the following Scheme expression: - -@example -(lambda (x) (+ x 1)) -@end example - -The corresponding (unoptimized) GLIL code, as shown by -@code{pprint-glil}, looks like this: - -@example -(@@asm (0 0 0 0) - (@@asm (1 0 0 0) ;; expect one arg. - (@@bind (x argument 0)) ;; debugging info - (module-ref #f +) ;; lookup `+' - (argument-ref 0) ;; push the argument onto - ;; the stack - (const 1) ;; push `1' - (tail-call 2) ;; call `+', with 2 args, - ;; using the same stack frame - (@@source 15 33)) ;; additional debugging info - (return 0)) -@end example - -This is not unlike the VM's assembly language described in -@ref{Instruction Set}. - -@node The Assembler, , GLIL, The Compiler -@section The Assembler - -@findex code->bytes - -The final compilation step consists in converting the GLIL instruction -sequence into VM bytecode. This is what the @code{assemble} procedure -defined in the @code{(system vm assemble)} module is for. It relies -on the @code{code->bytes} procedure of the @code{(system vm conv)} -module to convert instructions (represented as lists whose @code{car} -is a symbol naming the instruction, e.g. @code{object-ref}, -@pxref{Instruction Set}) into binary code, or @dfn{bytecode}. -Bytecode itself is represented using SRFI-4 byte vectors, -@inforef{SRFI-4, SRFI-4 homogeneous numeric vectors, guile}. - - -@deffn @scmproc{} assemble glil environment . opts -Return a binary representation of @var{glil} (bytecode), either in the -form of an SRFI-4 @code{u8vector} or a @code{} object. -[FIXME: Why is that?] -@end deffn - - - -@c ********************************************************************* -@node Concept Index, Function and Instruction Index, The Compiler, Top -@unnumbered Concept Index -@printindex cp - -@node Function and Instruction Index, Command and Variable Index, Concept Index, Top -@unnumbered Function and Instruction Index -@printindex fn - -@node Command and Variable Index, , Function and Instruction Index, Top -@unnumbered Command and Variable Index -@printindex vr - -@bye - -@c Local Variables: -@c ispell-local-dictionary: "american"; -@c End: - -@c LocalWords: bytecode diff --git a/doc/maint/docstring.el b/doc/maint/docstring.el index 2b5639eb6..ef271930f 100644 --- a/doc/maint/docstring.el +++ b/doc/maint/docstring.el @@ -2,22 +2,22 @@ ;;; ;;; Copyright (C) 2001, 2004 Neil Jerram ;;; -;;; This file is not part of GNU Emacs, but the same permissions apply. +;;; This file is not part of GUILE, but the same permissions apply. ;;; -;;; GNU Emacs 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, or (at your option) -;;; any later version. +;;; GUILE is free software; you can redistribute it and/or modify it +;;; under the terms of the GNU Lesser General Public License as +;;; published by the Free Software Foundation; either version 3, or +;;; (at your option) any later version. ;;; -;;; GNU Emacs 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. +;;; GUILE is distributed in the hope that it will be useful, but +;;; WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;; Lesser General Public License for more details. ;;; -;;; You should have received a copy of the GNU General Public License -;;; along with GNU Emacs; see the file COPYING. If not, write to the -;;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;; Boston, MA 02110-1301, USA. +;;; You should have received a copy of the GNU Lesser General Public +;;; License along with GUILE; see the file COPYING.LESSER. If not, +;;; write to the Free Software Foundation, Inc., 51 Franklin Street, +;;; Fifth Floor, Boston, MA 02110-1301, USA. ;;; Commentary: diff --git a/doc/maint/guile.texi b/doc/maint/guile.texi index ac0833421..4ef4aab18 100644 --- a/doc/maint/guile.texi +++ b/doc/maint/guile.texi @@ -204,7 +204,7 @@ Execute all thunks from the asyncs of the list @var{list_of_a}. @deffn {Scheme Procedure} system-async thunk @deffnx {C Function} scm_system_async (thunk) This function is deprecated. You can use @var{thunk} directly -instead of explicitely creating an async object. +instead of explicitly creating an async object. @end deffn diff --git a/doc/oldfmt.c b/doc/oldfmt.c index fc82ba92a..f60afeddd 100644 --- a/doc/oldfmt.c +++ b/doc/oldfmt.c @@ -1,18 +1,19 @@ /* Copyright (C) 2000,2001, 2006, 2008 Free Software Foundation, Inc. * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3, 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 * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * License along with this software; see the file COPYING.LESSER. If + * not, write to the Free Software Foundation, Inc., 51 Franklin + * Street, Fifth Floor, Boston, MA 02110-1301 USA */ diff --git a/doc/r5rs/Makefile.am b/doc/r5rs/Makefile.am index 4af0c951a..c64e4ffb1 100644 --- a/doc/r5rs/Makefile.am +++ b/doc/r5rs/Makefile.am @@ -4,20 +4,20 @@ ## ## This file is part of GUILE. ## -## GUILE 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, or +## GUILE is free software; you can redistribute it and/or modify it +## under the terms of the GNU Lesser General Public License as +## published by the Free Software Foundation; either version 3, or ## (at your option) any later version. -## +## ## GUILE 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 GUILE; see the file COPYING. If not, write -## to the Free Software Foundation, Inc., 51 Franklin Street, Fifth -## Floor, Boston, MA 02110-1301 USA +## GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with GUILE; see the file COPYING.LESSER. If not, +## write to the Free Software Foundation, Inc., 51 Franklin Street, +## Fifth Floor, Boston, MA 02110-1301 USA AUTOMAKE_OPTIONS = gnu diff --git a/doc/ref/Makefile.am b/doc/ref/Makefile.am index 9799a5e0b..abf42edfe 100644 --- a/doc/ref/Makefile.am +++ b/doc/ref/Makefile.am @@ -4,20 +4,20 @@ ## ## This file is part of GUILE. ## -## GUILE 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, or +## GUILE is free software; you can redistribute it and/or modify it +## under the terms of the GNU Lesser General Public License as +## published by the Free Software Foundation; either version 3, or ## (at your option) any later version. ## ## GUILE 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. +## GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU General Public -## License along with GUILE; see the file COPYING. If not, write -## to the Free Software Foundation, Inc., 51 Franklin Street, Fifth -## Floor, Boston, MA 02110-1301 USA +## You should have received a copy of the GNU Lesser General Public +## License along with GUILE; see the file COPYING.LESSER. If not, +## write to the Free Software Foundation, Inc., 51 Franklin Street, +## Fifth Floor, Boston, MA 02110-1301 USA AUTOMAKE_OPTIONS = gnu @@ -89,8 +89,9 @@ include $(top_srcdir)/am/pre-inst-guile # Automated snarfing autoconf.texi: autoconf-macros.texi -autoconf-macros.texi: $(top_srcdir)/guile-config/guile.m4 - $(preinstguiletool)/snarf-guile-m4-docs $(top_srcdir)/guile-config/guile.m4 \ +autoconf-macros.texi: $(top_srcdir)/meta/guile.m4 + GUILE_AUTO_COMPILE=0 $(top_builddir)/meta/uninstalled-env guile-tools \ + snarf-guile-m4-docs $(top_srcdir)/meta/guile.m4 \ > $(srcdir)/$@ lib-version.texi: $(top_srcdir)/GUILE-VERSION diff --git a/doc/ref/api-binding.texi b/doc/ref/api-binding.texi index b42f5567f..e53c48040 100644 --- a/doc/ref/api-binding.texi +++ b/doc/ref/api-binding.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Guile Reference Manual. -@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004 +@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2009 @c Free Software Foundation, Inc. @c See the file guile.texi for copying conditions. @@ -271,10 +271,16 @@ with duplicate bindings. Guile provides a procedure for checking whether a symbol is bound in the top level environment. -@c NJFIXME explain [env] -@deffn {Scheme Procedure} defined? sym [env] -@deffnx {C Function} scm_defined_p (sym, env) -Return @code{#t} if @var{sym} is defined in the lexical environment @var{env}. When @var{env} is not specified, look in the top-level environment as defined by the current module. +@deffn {Scheme Procedure} defined? sym [module] +@deffnx {C Function} scm_defined_p (sym, module) +Return @code{#t} if @var{sym} is defined in the module @var{module} or +the current module when @var{module} is not specified; otherwise return +@code{#f}. + +Up to Guile 1.8, the second optional argument had to be @dfn{lexical +environment} as returned by @code{the-environment}, for example. The +behavior of this function remains unchanged when the second argument is +omitted. @end deffn diff --git a/doc/ref/api-compound.texi b/doc/ref/api-compound.texi index f3fe9584a..7eccb8690 100644 --- a/doc/ref/api-compound.texi +++ b/doc/ref/api-compound.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Guile Reference Manual. -@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 +@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009 @c Free Software Foundation, Inc. @c See the file guile.texi for copying conditions. @@ -1405,6 +1405,12 @@ C}), but returns a pointer to the elements of a uniform numeric vector of the indicated kind. @end deftypefn +Uniform numeric vectors can be written to and read from input/output +ports using the procedures listed below. However, bytevectors may often +be more convenient for binary input/output since they provide more +flexibility in the interpretation of raw byte sequences +(@pxref{Bytevectors}). + @deffn {Scheme Procedure} uniform-vector-read! uvec [port_or_fd [start [end]]] @deffnx {C Function} scm_uniform_vector_read_x (uvec, port_or_fd, start, end) Fill the elements of @var{uvec} by reading @@ -1643,18 +1649,18 @@ and writing. @subsection Generalized Vectors Guile has a number of data types that are generally vector-like: -strings, uniform numeric vectors, bitvectors, and of course ordinary -vectors of arbitrary Scheme values. These types are disjoint: a -Scheme value belongs to at most one of the four types listed above. +strings, uniform numeric vectors, bytevectors, bitvectors, and of course +ordinary vectors of arbitrary Scheme values. These types are disjoint: +a Scheme value belongs to at most one of the five types listed above. If you want to gloss over this distinction and want to treat all four types with common code, you can use the procedures in this section. They work with the @emph{generalized vector} type, which is the union -of the four vector-like types. +of the five vector-like types. @deffn {Scheme Procedure} generalized-vector? obj @deffnx {C Function} scm_generalized_vector_p (obj) -Return @code{#t} if @var{obj} is a vector, string, +Return @code{#t} if @var{obj} is a vector, bytevector, string, bitvector, or uniform numeric vector. @end deffn @@ -1743,9 +1749,9 @@ matrix with zero columns and 3 rows is different from a matrix with 3 columns and zero rows, which again is different from a vector of length zero. -Generalized vectors, such as strings, uniform numeric vectors, bit -vectors and ordinary vectors, are the special case of one dimensional -arrays. +Generalized vectors, such as strings, uniform numeric vectors, +bytevectors, bit vectors and ordinary vectors, are the special case of +one dimensional arrays. @menu * Array Syntax:: @@ -1828,6 +1834,16 @@ is a rank-zero array with contents 12. @end table +In addition, bytevectors are also arrays, but use a different syntax +(@pxref{Bytevectors}): + +@table @code + +@item #vu8(1 2 3) +is a 3-byte long bytevector, with contents 1, 2, 3. + +@end table + @node Array Procedures @subsubsection Array Procedures @@ -2342,21 +2358,13 @@ the danger of a deadlock. In a multi-threaded program, you will need additional synchronization to avoid modifying reserved arrays.) You must take care to always unreserve an array after reserving it, -also in the presence of non-local exits. To simplify this, reserving -and unreserving work like a dynwind context (@pxref{Dynamic Wind}): a -call to @code{scm_array_get_handle} can be thought of as beginning a -dynwind context and @code{scm_array_handle_release} as ending it. -When a non-local exit happens between these two calls, the array is -implicitely unreserved. +even in the presence of non-local exits. If a non-local exit can +happen between these two calls, you should install a dynwind context +that releases the array when it is left (@pxref{Dynamic Wind}). -That is, you need to properly pair reserving and unreserving in your -code, but you don't need to worry about non-local exits. - -These calls and other pairs of calls that establish dynwind contexts -need to be properly nested. If you begin a context prior to reserving -an array, you need to unreserve the array before ending the context. -Likewise, when reserving two or more arrays in a certain order, you -need to unreserve them in the opposite order. +In addition, array reserving and unreserving must be properly +paired. For instance, when reserving two or more arrays in a certain +order, you need to unreserve them in the opposite order. Once you have reserved an array and have retrieved the pointer to its elements, you must figure out the layout of the elements in memory. diff --git a/doc/ref/api-data.texi b/doc/ref/api-data.texi index e1db2a612..6e1a67ae1 100755 --- a/doc/ref/api-data.texi +++ b/doc/ref/api-data.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Guile Reference Manual. -@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008 +@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009 @c Free Software Foundation, Inc. @c See the file guile.texi for copying conditions. @@ -45,6 +45,7 @@ For the documentation of such @dfn{compound} data types, see * Characters:: Single characters. * Character Sets:: Sets of characters. * Strings:: Sequences of characters. +* Bytevectors:: Sequences of bytes. * Regular Expressions:: Pattern matching and substitution. * Symbols:: Symbols. * Keywords:: Self-quoting, customizable display keywords. @@ -331,7 +332,7 @@ integers. The motivation for this behavior is that the inexactness of a number should not be lost silently. If you want to allow inexact integers, -you can explicitely insert a call to @code{inexact->exact} or to its C +you can explicitly insert a call to @code{inexact->exact} or to its C equivalent @code{scm_inexact_to_exact}. (Only inexact integers will be converted by this call into exact integers; inexact non-integers will become exact fractions.) @@ -3746,6 +3747,445 @@ is larger than @var{max_len}, only @var{max_len} bytes have been stored and you probably need to try again with a larger buffer. @end deftypefn +@node Bytevectors +@subsection Bytevectors + +@cindex bytevector +@cindex R6RS + +A @dfn{bytevector} is a raw bit string. The @code{(rnrs bytevector)} +module provides the programming interface specified by the +@uref{http://www.r6rs.org/, Revised^6 Report on the Algorithmic Language +Scheme (R6RS)}. It contains procedures to manipulate bytevectors and +interpret their contents in a number of ways: bytevector contents can be +accessed as signed or unsigned integer of various sizes and endianness, +as IEEE-754 floating point numbers, or as strings. It is a useful tool +to encode and decode binary data. + +The R6RS (Section 4.3.4) specifies an external representation for +bytevectors, whereby the octets (integers in the range 0--255) contained +in the bytevector are represented as a list prefixed by @code{#vu8}: + +@lisp +#vu8(1 53 204) +@end lisp + +denotes a 3-byte bytevector containing the octets 1, 53, and 204. Like +string literals, booleans, etc., bytevectors are ``self-quoting'', i.e., +they do not need to be quoted: + +@lisp +#vu8(1 53 204) +@result{} #vu8(1 53 204) +@end lisp + +Bytevectors can be used with the binary input/output primitives of the +R6RS (@pxref{R6RS I/O Ports}). + +@menu +* Bytevector Endianness:: Dealing with byte order. +* Bytevector Manipulation:: Creating, copying, manipulating bytevectors. +* Bytevectors as Integers:: Interpreting bytes as integers. +* Bytevectors and Integer Lists:: Converting to/from an integer list. +* Bytevectors as Floats:: Interpreting bytes as real numbers. +* Bytevectors as Strings:: Interpreting bytes as Unicode strings. +* Bytevectors as Generalized Vectors:: Guile extension to the bytevector API. +@end menu + +@node Bytevector Endianness +@subsubsection Endianness + +@cindex endianness +@cindex byte order +@cindex word order + +Some of the following procedures take an @var{endianness} parameter. +The @dfn{endianness} is defined as the order of bytes in multi-byte +numbers: numbers encoded in @dfn{big endian} have their most +significant bytes written first, whereas numbers encoded in +@dfn{little endian} have their least significant bytes +first@footnote{Big-endian and little-endian are the most common +``endiannesses'', but others do exist. For instance, the GNU MP +library allows @dfn{word order} to be specified independently of +@dfn{byte order} (@pxref{Integer Import and Export,,, gmp, The GNU +Multiple Precision Arithmetic Library Manual}).}. + +Little-endian is the native endianness of the IA32 architecture and +its derivatives, while big-endian is native to SPARC and PowerPC, +among others. The @code{native-endianness} procedure returns the +native endianness of the machine it runs on. + +@deffn {Scheme Procedure} native-endianness +@deffnx {C Function} scm_native_endianness () +Return a value denoting the native endianness of the host machine. +@end deffn + +@deffn {Scheme Macro} endianness symbol +Return an object denoting the endianness specified by @var{symbol}. If +@var{symbol} is neither @code{big} nor @code{little} then an error is +raised at expand-time. +@end deffn + +@defvr {C Variable} scm_endianness_big +@defvrx {C Variable} scm_endianness_little +The objects denoting big- and little-endianness, respectively. +@end defvr + + +@node Bytevector Manipulation +@subsubsection Manipulating Bytevectors + +Bytevectors can be created, copied, and analyzed with the following +procedures and C functions. + +@deffn {Scheme Procedure} make-bytevector len [fill] +@deffnx {C Function} scm_make_bytevector (len, fill) +@deffnx {C Function} scm_c_make_bytevector (size_t len) +Return a new bytevector of @var{len} bytes. Optionally, if @var{fill} +is given, fill it with @var{fill}; @var{fill} must be in the range +[-128,255]. +@end deffn + +@deffn {Scheme Procedure} bytevector? obj +@deffnx {C Function} scm_bytevector_p (obj) +Return true if @var{obj} is a bytevector. +@end deffn + +@deftypefn {C Function} int scm_is_bytevector (SCM obj) +Equivalent to @code{scm_is_true (scm_bytevector_p (obj))}. +@end deftypefn + +@deffn {Scheme Procedure} bytevector-length bv +@deffnx {C Function} scm_bytevector_length (bv) +Return the length in bytes of bytevector @var{bv}. +@end deffn + +@deftypefn {C Function} size_t scm_c_bytevector_length (SCM bv) +Likewise, return the length in bytes of bytevector @var{bv}. +@end deftypefn + +@deffn {Scheme Procedure} bytevector=? bv1 bv2 +@deffnx {C Function} scm_bytevector_eq_p (bv1, bv2) +Return is @var{bv1} equals to @var{bv2}---i.e., if they have the same +length and contents. +@end deffn + +@deffn {Scheme Procedure} bytevector-fill! bv fill +@deffnx {C Function} scm_bytevector_fill_x (bv, fill) +Fill bytevector @var{bv} with @var{fill}, a byte. +@end deffn + +@deffn {Scheme Procedure} bytevector-copy! source source-start target target-start len +@deffnx {C Function} scm_bytevector_copy_x (source, source_start, target, target_start, len) +Copy @var{len} bytes from @var{source} into @var{target}, starting +reading from @var{source-start} (a positive index within @var{source}) +and start writing at @var{target-start}. +@end deffn + +@deffn {Scheme Procedure} bytevector-copy bv +@deffnx {C Function} scm_bytevector_copy (bv) +Return a newly allocated copy of @var{bv}. +@end deffn + +@deftypefn {C Function} scm_t_uint8 scm_c_bytevector_ref (SCM bv, size_t index) +Return the byte at @var{index} in bytevector @var{bv}. +@end deftypefn + +@deftypefn {C Function} void scm_c_bytevector_set_x (SCM bv, size_t index, scm_t_uint8 value) +Set the byte at @var{index} in @var{bv} to @var{value}. +@end deftypefn + +Low-level C macros are available. They do not perform any +type-checking; as such they should be used with care. + +@deftypefn {C Macro} size_t SCM_BYTEVECTOR_LENGTH (bv) +Return the length in bytes of bytevector @var{bv}. +@end deftypefn + +@deftypefn {C Macro} {signed char *} SCM_BYTEVECTOR_CONTENTS (bv) +Return a pointer to the contents of bytevector @var{bv}. +@end deftypefn + + +@node Bytevectors as Integers +@subsubsection Interpreting Bytevector Contents as Integers + +The contents of a bytevector can be interpreted as a sequence of +integers of any given size, sign, and endianness. + +@lisp +(let ((bv (make-bytevector 4))) + (bytevector-u8-set! bv 0 #x12) + (bytevector-u8-set! bv 1 #x34) + (bytevector-u8-set! bv 2 #x56) + (bytevector-u8-set! bv 3 #x78) + + (map (lambda (number) + (number->string number 16)) + (list (bytevector-u8-ref bv 0) + (bytevector-u16-ref bv 0 (endianness big)) + (bytevector-u32-ref bv 0 (endianness little))))) + +@result{} ("12" "1234" "78563412") +@end lisp + +The most generic procedures to interpret bytevector contents as integers +are described below. + +@deffn {Scheme Procedure} bytevector-uint-ref bv index endianness size +@deffnx {Scheme Procedure} bytevector-sint-ref bv index endianness size +@deffnx {C Function} scm_bytevector_uint_ref (bv, index, endianness, size) +@deffnx {C Function} scm_bytevector_sint_ref (bv, index, endianness, size) +Return the @var{size}-byte long unsigned (resp. signed) integer at +index @var{index} in @var{bv}, decoded according to @var{endianness}. +@end deffn + +@deffn {Scheme Procedure} bytevector-uint-set! bv index value endianness size +@deffnx {Scheme Procedure} bytevector-sint-set! bv index value endianness size +@deffnx {C Function} scm_bytevector_uint_set_x (bv, index, value, endianness, size) +@deffnx {C Function} scm_bytevector_sint_set_x (bv, index, value, endianness, size) +Set the @var{size}-byte long unsigned (resp. signed) integer at +@var{index} to @var{value}, encoded according to @var{endianness}. +@end deffn + +The following procedures are similar to the ones above, but specialized +to a given integer size: + +@deffn {Scheme Procedure} bytevector-u8-ref bv index +@deffnx {Scheme Procedure} bytevector-s8-ref bv index +@deffnx {Scheme Procedure} bytevector-u16-ref bv index endianness +@deffnx {Scheme Procedure} bytevector-s16-ref bv index endianness +@deffnx {Scheme Procedure} bytevector-u32-ref bv index endianness +@deffnx {Scheme Procedure} bytevector-s32-ref bv index endianness +@deffnx {Scheme Procedure} bytevector-u64-ref bv index endianness +@deffnx {Scheme Procedure} bytevector-s64-ref bv index endianness +@deffnx {C Function} scm_bytevector_u8_ref (bv, index) +@deffnx {C Function} scm_bytevector_s8_ref (bv, index) +@deffnx {C Function} scm_bytevector_u16_ref (bv, index, endianness) +@deffnx {C Function} scm_bytevector_s16_ref (bv, index, endianness) +@deffnx {C Function} scm_bytevector_u32_ref (bv, index, endianness) +@deffnx {C Function} scm_bytevector_s32_ref (bv, index, endianness) +@deffnx {C Function} scm_bytevector_u64_ref (bv, index, endianness) +@deffnx {C Function} scm_bytevector_s64_ref (bv, index, endianness) +Return the unsigned @var{n}-bit (signed) integer (where @var{n} is 8, +16, 32 or 64) from @var{bv} at @var{index}, decoded according to +@var{endianness}. +@end deffn + +@deffn {Scheme Procedure} bytevector-u8-set! bv index value +@deffnx {Scheme Procedure} bytevector-s8-set! bv index value +@deffnx {Scheme Procedure} bytevector-u16-set! bv index value endianness +@deffnx {Scheme Procedure} bytevector-s16-set! bv index value endianness +@deffnx {Scheme Procedure} bytevector-u32-set! bv index value endianness +@deffnx {Scheme Procedure} bytevector-s32-set! bv index value endianness +@deffnx {Scheme Procedure} bytevector-u64-set! bv index value endianness +@deffnx {Scheme Procedure} bytevector-s64-set! bv index value endianness +@deffnx {C Function} scm_bytevector_u8_set_x (bv, index, value) +@deffnx {C Function} scm_bytevector_s8_set_x (bv, index, value) +@deffnx {C Function} scm_bytevector_u16_set_x (bv, index, value, endianness) +@deffnx {C Function} scm_bytevector_s16_set_x (bv, index, value, endianness) +@deffnx {C Function} scm_bytevector_u32_set_x (bv, index, value, endianness) +@deffnx {C Function} scm_bytevector_s32_set_x (bv, index, value, endianness) +@deffnx {C Function} scm_bytevector_u64_set_x (bv, index, value, endianness) +@deffnx {C Function} scm_bytevector_s64_set_x (bv, index, value, endianness) +Store @var{value} as an @var{n}-bit (signed) integer (where @var{n} is +8, 16, 32 or 64) in @var{bv} at @var{index}, encoded according to +@var{endianness}. +@end deffn + +Finally, a variant specialized for the host's endianness is available +for each of these functions (with the exception of the @code{u8} +accessors, for obvious reasons): + +@deffn {Scheme Procedure} bytevector-u16-native-ref bv index +@deffnx {Scheme Procedure} bytevector-s16-native-ref bv index +@deffnx {Scheme Procedure} bytevector-u32-native-ref bv index +@deffnx {Scheme Procedure} bytevector-s32-native-ref bv index +@deffnx {Scheme Procedure} bytevector-u64-native-ref bv index +@deffnx {Scheme Procedure} bytevector-s64-native-ref bv index +@deffnx {C Function} scm_bytevector_u16_native_ref (bv, index) +@deffnx {C Function} scm_bytevector_s16_native_ref (bv, index) +@deffnx {C Function} scm_bytevector_u32_native_ref (bv, index) +@deffnx {C Function} scm_bytevector_s32_native_ref (bv, index) +@deffnx {C Function} scm_bytevector_u64_native_ref (bv, index) +@deffnx {C Function} scm_bytevector_s64_native_ref (bv, index) +Return the unsigned @var{n}-bit (signed) integer (where @var{n} is 8, +16, 32 or 64) from @var{bv} at @var{index}, decoded according to the +host's native endianness. +@end deffn + +@deffn {Scheme Procedure} bytevector-u16-native-set! bv index value +@deffnx {Scheme Procedure} bytevector-s16-native-set! bv index value +@deffnx {Scheme Procedure} bytevector-u32-native-set! bv index value +@deffnx {Scheme Procedure} bytevector-s32-native-set! bv index value +@deffnx {Scheme Procedure} bytevector-u64-native-set! bv index value +@deffnx {Scheme Procedure} bytevector-s64-native-set! bv index value +@deffnx {C Function} scm_bytevector_u16_native_set_x (bv, index, value) +@deffnx {C Function} scm_bytevector_s16_native_set_x (bv, index, value) +@deffnx {C Function} scm_bytevector_u32_native_set_x (bv, index, value) +@deffnx {C Function} scm_bytevector_s32_native_set_x (bv, index, value) +@deffnx {C Function} scm_bytevector_u64_native_set_x (bv, index, value) +@deffnx {C Function} scm_bytevector_s64_native_set_x (bv, index, value) +Store @var{value} as an @var{n}-bit (signed) integer (where @var{n} is +8, 16, 32 or 64) in @var{bv} at @var{index}, encoded according to the +host's native endianness. +@end deffn + + +@node Bytevectors and Integer Lists +@subsubsection Converting Bytevectors to/from Integer Lists + +Bytevector contents can readily be converted to/from lists of signed or +unsigned integers: + +@lisp +(bytevector->sint-list (u8-list->bytevector (make-list 4 255)) + (endianness little) 2) +@result{} (-1 -1) +@end lisp + +@deffn {Scheme Procedure} bytevector->u8-list bv +@deffnx {C Function} scm_bytevector_to_u8_list (bv) +Return a newly allocated list of unsigned 8-bit integers from the +contents of @var{bv}. +@end deffn + +@deffn {Scheme Procedure} u8-list->bytevector lst +@deffnx {C Function} scm_u8_list_to_bytevector (lst) +Return a newly allocated bytevector consisting of the unsigned 8-bit +integers listed in @var{lst}. +@end deffn + +@deffn {Scheme Procedure} bytevector->uint-list bv endianness size +@deffnx {Scheme Procedure} bytevector->sint-list bv endianness size +@deffnx {C Function} scm_bytevector_to_uint_list (bv, endianness, size) +@deffnx {C Function} scm_bytevector_to_sint_list (bv, endianness, size) +Return a list of unsigned (resp. signed) integers of @var{size} bytes +representing the contents of @var{bv}, decoded according to +@var{endianness}. +@end deffn + +@deffn {Scheme Procedure} uint-list->bytevector lst endianness size +@deffnx {Scheme Procedure} sint-list->bytevector lst endianness size +@deffnx {C Function} scm_uint_list_to_bytevector (lst, endianness, size) +@deffnx {C Function} scm_sint_list_to_bytevector (lst, endianness, size) +Return a new bytevector containing the unsigned (resp. signed) integers +listed in @var{lst} and encoded on @var{size} bytes according to +@var{endianness}. +@end deffn + +@node Bytevectors as Floats +@subsubsection Interpreting Bytevector Contents as Floating Point Numbers + +@cindex IEEE-754 floating point numbers + +Bytevector contents can also be accessed as IEEE-754 single- or +double-precision floating point numbers (respectively 32 and 64-bit +long) using the procedures described here. + +@deffn {Scheme Procedure} bytevector-ieee-single-ref bv index endianness +@deffnx {Scheme Procedure} bytevector-ieee-double-ref bv index endianness +@deffnx {C Function} scm_bytevector_ieee_single_ref (bv, index, endianness) +@deffnx {C Function} scm_bytevector_ieee_double_ref (bv, index, endianness) +Return the IEEE-754 single-precision floating point number from @var{bv} +at @var{index} according to @var{endianness}. +@end deffn + +@deffn {Scheme Procedure} bytevector-ieee-single-set! bv index value endianness +@deffnx {Scheme Procedure} bytevector-ieee-double-set! bv index value endianness +@deffnx {C Function} scm_bytevector_ieee_single_set_x (bv, index, value, endianness) +@deffnx {C Function} scm_bytevector_ieee_double_set_x (bv, index, value, endianness) +Store real number @var{value} in @var{bv} at @var{index} according to +@var{endianness}. +@end deffn + +Specialized procedures are also available: + +@deffn {Scheme Procedure} bytevector-ieee-single-native-ref bv index +@deffnx {Scheme Procedure} bytevector-ieee-double-native-ref bv index +@deffnx {C Function} scm_bytevector_ieee_single_native_ref (bv, index) +@deffnx {C Function} scm_bytevector_ieee_double_native_ref (bv, index) +Return the IEEE-754 single-precision floating point number from @var{bv} +at @var{index} according to the host's native endianness. +@end deffn + +@deffn {Scheme Procedure} bytevector-ieee-single-native-set! bv index value +@deffnx {Scheme Procedure} bytevector-ieee-double-native-set! bv index value +@deffnx {C Function} scm_bytevector_ieee_single_native_set_x (bv, index, value) +@deffnx {C Function} scm_bytevector_ieee_double_native_set_x (bv, index, value) +Store real number @var{value} in @var{bv} at @var{index} according to +the host's native endianness. +@end deffn + + +@node Bytevectors as Strings +@subsubsection Interpreting Bytevector Contents as Unicode Strings + +@cindex Unicode string encoding + +Bytevector contents can also be interpreted as Unicode strings encoded +in one of the most commonly available encoding formats@footnote{Guile +1.8 does @emph{not} support Unicode strings. Therefore, the procedures +described here assume that Guile strings are internally encoded +according to the current locale. For instance, if @code{$LC_CTYPE} is +@code{fr_FR.ISO-8859-1}, then @code{string->utf-8} @i{et al.} will +assume that Guile strings are Latin-1-encoded.}. + +@lisp +(utf8->string (u8-list->bytevector '(99 97 102 101))) +@result{} "cafe" + +(string->utf8 "caf@'e") ;; SMALL LATIN LETTER E WITH ACUTE ACCENT +@result{} #vu8(99 97 102 195 169) +@end lisp + +@deffn {Scheme Procedure} string->utf8 str +@deffnx {Scheme Procedure} string->utf16 str +@deffnx {Scheme Procedure} string->utf32 str +@deffnx {C Function} scm_string_to_utf8 (str) +@deffnx {C Function} scm_string_to_utf16 (str) +@deffnx {C Function} scm_string_to_utf32 (str) +Return a newly allocated bytevector that contains the UTF-8, UTF-16, or +UTF-32 (aka. UCS-4) encoding of @var{str}. +@end deffn + +@deffn {Scheme Procedure} utf8->string utf +@deffnx {Scheme Procedure} utf16->string utf +@deffnx {Scheme Procedure} utf32->string utf +@deffnx {C Function} scm_utf8_to_string (utf) +@deffnx {C Function} scm_utf16_to_string (utf) +@deffnx {C Function} scm_utf32_to_string (utf) +Return a newly allocated string that contains from the UTF-8-, UTF-16-, +or UTF-32-decoded contents of bytevector @var{utf}. +@end deffn + +@node Bytevectors as Generalized Vectors +@subsubsection Accessing Bytevectors with the Generalized Vector API + +As an extension to the R6RS, Guile allows bytevectors to be manipulated +with the @dfn{generalized vector} procedures (@pxref{Generalized +Vectors}). This also allows bytevectors to be accessed using the +generic @dfn{array} procedures (@pxref{Array Procedures}). When using +these APIs, bytes are accessed one at a time as 8-bit unsigned integers: + +@example +(define bv #vu8(0 1 2 3)) + +(generalized-vector? bv) +@result{} #t + +(generalized-vector-ref bv 2) +@result{} 2 + +(generalized-vector-set! bv 2 77) +(array-ref bv 2) +@result{} 77 + +(array-type bv) +@result{} vu8 +@end example + + @node Regular Expressions @subsection Regular Expressions @tpindex Regular expressions diff --git a/doc/ref/api-init.texi b/doc/ref/api-init.texi index 0e4e8b8b7..f9714c3b6 100644 --- a/doc/ref/api-init.texi +++ b/doc/ref/api-init.texi @@ -61,7 +61,7 @@ Arrange things so that all of the code in the current thread executes as if from within a call to @code{scm_with_guile}. That is, all functions called by the current thread can assume that @code{SCM} values on their stack frames are protected from the garbage collector (except when the -thread has explicitely left guile mode, of course). +thread has explicitly left guile mode, of course). When @code{scm_init_guile} is called from a thread that already has been in guile mode once, nothing happens. This behavior matters when you diff --git a/doc/ref/api-io.texi b/doc/ref/api-io.texi index f69d07ede..b0b57412a 100644 --- a/doc/ref/api-io.texi +++ b/doc/ref/api-io.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Guile Reference Manual. -@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2007 +@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2007, 2009 @c Free Software Foundation, Inc. @c See the file guile.texi for copying conditions. @@ -18,6 +18,7 @@ * Block Reading and Writing:: Reading and writing blocks of text. * Default Ports:: Defaults for input, output and errors. * Port Types:: Types of port and how to make them. +* R6RS I/O Ports:: The R6RS port API. * I/O Extensions:: Using and extending ports in C. @end menu @@ -1023,6 +1024,269 @@ documentation for @code{open-file} in @ref{File Ports}. @end deffn +@node R6RS I/O Ports +@subsection R6RS I/O Ports + +@cindex R6RS +@cindex R6RS ports + +The I/O port API of the @uref{http://www.r6rs.org/, Revised Report^6 on +the Algorithmic Language Scheme (R6RS)} is provided by the @code{(rnrs +io ports)} module. It provides features, such as binary I/O and Unicode +string I/O, that complement or refine Guile's historical port API +presented above (@pxref{Input and Output}). + +@c FIXME: Update description when implemented. +@emph{Note}: The implementation of this R6RS API is currently far from +complete, notably due to the lack of support for Unicode I/O and strings. + +@menu +* R6RS End-of-File:: The end-of-file object. +* R6RS Port Manipulation:: Manipulating R6RS ports. +* R6RS Binary Input:: Binary input. +* R6RS Binary Output:: Binary output. +@end menu + +@node R6RS End-of-File +@subsubsection The End-of-File Object + +@cindex EOF +@cindex end-of-file + +R5RS' @code{eof-object?} procedure is provided by the @code{(rnrs io +ports)} module: + +@deffn {Scheme Procedure} eof-object? obj +@deffnx {C Function} scm_eof_object_p (obj) +Return true if @var{obj} is the end-of-file (EOF) object. +@end deffn + +In addition, the following procedure is provided: + +@deffn {Scheme Procedure} eof-object +@deffnx {C Function} scm_eof_object () +Return the end-of-file (EOF) object. + +@lisp +(eof-object? (eof-object)) +@result{} #t +@end lisp +@end deffn + + +@node R6RS Port Manipulation +@subsubsection Port Manipulation + +The procedures listed below operate on any kind of R6RS I/O port. + +@deffn {Scheme Procedure} port-position port +If @var{port} supports it (see below), return the offset (an integer) +indicating where the next octet will be read from/written to in +@var{port}. If @var{port} does not support this operation, an error +condition is raised. + +This is similar to Guile's @code{seek} procedure with the +@code{SEEK_CUR} argument (@pxref{Random Access}). +@end deffn + +@deffn {Scheme Procedure} port-has-port-position? port +Return @code{#t} is @var{port} supports @code{port-position}. +@end deffn + +@deffn {Scheme Procedure} set-port-position! port offset +If @var{port} supports it (see below), set the position where the next +octet will be read from/written to @var{port} to @var{offset} (an +integer). If @var{port} does not support this operation, an error +condition is raised. + +This is similar to Guile's @code{seek} procedure with the +@code{SEEK_SET} argument (@pxref{Random Access}). +@end deffn + +@deffn {Scheme Procedure} port-has-set-port-position!? port +Return @code{#t} is @var{port} supports @code{set-port-position!}. +@end deffn + +@deffn {Scheme Procedure} call-with-port port proc +Call @var{proc}, passing it @var{port} and closing @var{port} upon exit +of @var{proc}. Return the return values of @var{proc}. +@end deffn + + +@node R6RS Binary Input +@subsubsection Binary Input + +@cindex binary input + +R6RS binary input ports can be created with the procedures described +below. + +@deffn {Scheme Procedure} open-bytevector-input-port bv [transcoder] +@deffnx {C Function} scm_open_bytevector_input_port (bv, transcoder) +Return an input port whose contents are drawn from bytevector @var{bv} +(@pxref{Bytevectors}). + +@c FIXME: Update description when implemented. +The @var{transcoder} argument is currently not supported. +@end deffn + +@cindex custom binary input ports + +@deffn {Scheme Procedure} make-custom-binary-input-port id read! get-position set-position! close +@deffnx {C Function} scm_make_custom_binary_input_port (id, read!, get-position, set-position!, close) +Return a new custom binary input port@footnote{This is similar in spirit +to Guile's @dfn{soft ports} (@pxref{Soft Ports}).} named @var{id} (a +string) whose input is drained by invoking @var{read!} and passing it a +bytevector, an index where bytes should be written, and the number of +bytes to read. The @code{read!} procedure must return an integer +indicating the number of bytes read, or @code{0} to indicate the +end-of-file. + +Optionally, if @var{get-position} is not @code{#f}, it must be a thunk +that will be called when @var{port-position} is invoked on the custom +binary port and should return an integer indicating the position within +the underlying data stream; if @var{get-position} was not supplied, the +returned port does not support @var{port-position}. + +Likewise, if @var{set-position!} is not @code{#f}, it should be a +one-argument procedure. When @var{set-port-position!} is invoked on the +custom binary input port, @var{set-position!} is passed an integer +indicating the position of the next byte is to read. + +Finally, if @var{close} is not @code{#f}, it must be a thunk. It is +invoked when the custom binary input port is closed. + +Using a custom binary input port, the @code{open-bytevector-input-port} +procedure could be implemented as follows: + +@lisp +(define (open-bytevector-input-port source) + (define position 0) + (define length (bytevector-length source)) + + (define (read! bv start count) + (let ((count (min count (- length position)))) + (bytevector-copy! source position + bv start count) + (set! position (+ position count)) + count)) + + (define (get-position) position) + + (define (set-position! new-position) + (set! position new-position)) + + (make-custom-binary-input-port "the port" read! + get-position + set-position!)) + +(read (open-bytevector-input-port (string->utf8 "hello"))) +@result{} hello +@end lisp +@end deffn + +@cindex binary input +Binary input is achieved using the procedures below: + +@deffn {Scheme Procedure} get-u8 port +@deffnx {C Function} scm_get_u8 (port) +Return an octet read from @var{port}, a binary input port, blocking as +necessary, or the end-of-file object. +@end deffn + +@deffn {Scheme Procedure} lookahead-u8 port +@deffnx {C Function} scm_lookahead_u8 (port) +Like @code{get-u8} but does not update @var{port}'s position to point +past the octet. +@end deffn + +@deffn {Scheme Procedure} get-bytevector-n port count +@deffnx {C Function} scm_get_bytevector_n (port, count) +Read @var{count} octets from @var{port}, blocking as necessary and +return a bytevector containing the octets read. If fewer bytes are +available, a bytevector smaller than @var{count} is returned. +@end deffn + +@deffn {Scheme Procedure} get-bytevector-n! port bv start count +@deffnx {C Function} scm_get_bytevector_n_x (port, bv, start, count) +Read @var{count} bytes from @var{port} and store them in @var{bv} +starting at index @var{start}. Return either the number of bytes +actually read or the end-of-file object. +@end deffn + +@deffn {Scheme Procedure} get-bytevector-some port +@deffnx {C Function} scm_get_bytevector_some (port) +Read from @var{port}, blocking as necessary, until data are available or +and end-of-file is reached. Return either a new bytevector containing +the data read or the end-of-file object. +@end deffn + +@deffn {Scheme Procedure} get-bytevector-all port +@deffnx {C Function} scm_get_bytevector_all (port) +Read from @var{port}, blocking as necessary, until the end-of-file is +reached. Return either a new bytevector containing the data read or the +end-of-file object (if no data were available). +@end deffn + +@node R6RS Binary Output +@subsubsection Binary Output + +Binary output ports can be created with the procedures below. + +@deffn {Scheme Procedure} open-bytevector-output-port [transcoder] +@deffnx {C Function} scm_open_bytevector_output_port (transcoder) +Return two values: a binary output port and a procedure. The latter +should be called with zero arguments to obtain a bytevector containing +the data accumulated by the port, as illustrated below. + +@lisp +(call-with-values + (lambda () + (open-bytevector-output-port)) + (lambda (port get-bytevector) + (display "hello" port) + (get-bytevector))) + +@result{} #vu8(104 101 108 108 111) +@end lisp + +@c FIXME: Update description when implemented. +The @var{transcoder} argument is currently not supported. +@end deffn + +@cindex custom binary output ports + +@deffn {Scheme Procedure} make-custom-binary-output-port id write! get-position set-position! close +@deffnx {C Function} scm_make_custom_binary_output_port (id, write!, get-position, set-position!, close) +Return a new custom binary output port named @var{id} (a string) whose +output is sunk by invoking @var{write!} and passing it a bytevector, an +index where bytes should be read from this bytevector, and the number of +bytes to be ``written''. The @code{write!} procedure must return an +integer indicating the number of bytes actually written; when it is +passed @code{0} as the number of bytes to write, it should behave as +though an end-of-file was sent to the byte sink. + +The other arguments are as for @code{make-custom-binary-input-port} +(@pxref{R6RS Binary Input, @code{make-custom-binary-input-port}}). +@end deffn + +@cindex binary output +Writing to a binary output port can be done using the following +procedures: + +@deffn {Scheme Procedure} put-u8 port octet +@deffnx {C Function} scm_put_u8 (port, octet) +Write @var{octet}, an integer in the 0--255 range, to @var{port}, a +binary output port. +@end deffn + +@deffn {Scheme Procedure} put-bytevector port bv [start [count]] +@deffnx {C Function} scm_put_bytevector (port, bv, start, count) +Write the contents of @var{bv} to @var{port}, optionally starting at +index @var{start} and limiting to @var{count} octets. +@end deffn + + @node I/O Extensions @subsection Using and Extending Ports in C @@ -1267,7 +1531,7 @@ implementations take care to avoid this problem. The procedure is set using -@deftypefun void scm_set_port_seek (scm_t_bits tc, off_t (*seek) (SCM port, off_t offset, int whence)) +@deftypefun void scm_set_port_seek (scm_t_bits tc, scm_t_off (*seek) (SCM port, scm_t_off offset, int whence)) @end deftypefun @item truncate @@ -1275,7 +1539,7 @@ Truncate the port data to be specified length. It can be assumed that the current state of @code{rw_active} is @code{SCM_PORT_NEITHER}. Set using -@deftypefun void scm_set_port_truncate (scm_t_bits tc, void (*truncate) (SCM port, off_t length)) +@deftypefun void scm_set_port_truncate (scm_t_bits tc, void (*truncate) (SCM port, scm_t_off length)) @end deftypefun @end table diff --git a/doc/ref/api-memory.texi b/doc/ref/api-memory.texi index 32d39982c..f492203f7 100644 --- a/doc/ref/api-memory.texi +++ b/doc/ref/api-memory.texi @@ -10,7 +10,7 @@ Guile uses a @emph{garbage collector} to manage most of its objects. While the garbage collector is designed to be mostly invisible, you -sometimes need to interact with it explicitely. +sometimes need to interact with it explicitly. See @ref{Garbage Collection} for a general discussion of how garbage collection relates to using Guile from C. @@ -201,7 +201,7 @@ below for a motivation. @deftypefn {C Function} void scm_gc_free (void *@var{mem}, size_t @var{size}, const char *@var{what}) Like @code{free}, but also call @code{scm_gc_unregister_collectable_memory}. -Note that you need to explicitely pass the @var{size} parameter. This +Note that you need to explicitly pass the @var{size} parameter. This is done since it should normally be easy to provide this parameter (for memory that is associated with GC controlled objects) and this frees us from tracking this value in the GC itself, which will keep diff --git a/doc/ref/api-procedures.texi b/doc/ref/api-procedures.texi index e3cf25823..8098b4ffb 100644 --- a/doc/ref/api-procedures.texi +++ b/doc/ref/api-procedures.texi @@ -162,18 +162,10 @@ appropriate module first, though: Returns @code{#t} iff @var{obj} is a compiled procedure. @end deffn -@deffn {Scheme Procedure} program-bytecode program -@deffnx {C Function} scm_program_bytecode (program) -Returns the object code associated with this program, as a -@code{u8vector}. -@end deffn - -@deffn {Scheme Procedure} program-base program -@deffnx {C Function} scm_program_base (program) -Returns the address in memory corresponding to the start of -@var{program}'s object code, as an integer. This is useful mostly when -you map the value of an instruction pointer from the VM to actual -instructions. +@deffn {Scheme Procedure} program-objcode program +@deffnx {C Function} scm_program_objcode (program) +Returns the object code associated with this program. @xref{Bytecode +and Objcode}, for more information. @end deffn @deffn {Scheme Procedure} program-objects program @@ -184,9 +176,9 @@ vector. @xref{VM Programs}, for more information. @deffn {Scheme Procedure} program-module program @deffnx {C Function} scm_program_module (program) -Returns the module that was current when this program was created. -Free variables in this program are looked up with respect to this -module. +Returns the module that was current when this program was created. Can +return @code{#f} if the compiler could determine that this information +was unnecessary. @end deffn @deffn {Scheme Procedure} program-external program @@ -250,9 +242,9 @@ REPL. The only tricky bit is that @var{extp} is a boolean, declaring whether the binding is heap-allocated or not. @xref{VM Concepts}, for more information. -Note that bindings information are stored in a program as part of its -metadata thunk, so including them in the generated object code does -not impose a runtime performance penalty. +Note that bindings information is stored in a program as part of its +metadata thunk, so including it in the generated object code does not +impose a runtime performance penalty. @end deffn @deffn {Scheme Procedure} program-sources program diff --git a/doc/ref/api-undocumented.texi b/doc/ref/api-undocumented.texi index 826b4d38b..ef1df19c5 100644 --- a/doc/ref/api-undocumented.texi +++ b/doc/ref/api-undocumented.texi @@ -257,7 +257,7 @@ otherwise return the first argument. @deffn {Scheme Procedure} system-async thunk @deffnx {C Function} scm_system_async (thunk) This function is deprecated. You can use @var{thunk} directly -instead of explicitely creating an async object. +instead of explicitly creating an async object. @end deffn diff --git a/doc/ref/autoconf.texi b/doc/ref/autoconf.texi index 83686dada..ba5800fc0 100644 --- a/doc/ref/autoconf.texi +++ b/doc/ref/autoconf.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Guile Reference Manual. -@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004 +@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2009 @c Free Software Foundation, Inc. @c See the file guile.texi for copying conditions. @@ -49,7 +49,7 @@ checks. @cindex autoconf GNU Guile provides a @dfn{pkg-config} description file, installed as -@file{@var{prefix}/lib/pkgconfig/guile-1.8.pc}, which contains all the +@file{@var{prefix}/lib/pkgconfig/guile-2.0.pc}, which contains all the information necessary to compile and link C applications that use Guile. The @code{pkg-config} program is able to read this file and provide this information to application programmers; it can be obtained at @@ -59,8 +59,8 @@ The following command lines give respectively the C compilation and link flags needed to build Guile-using programs: @example -pkg-config guile-1.8 --cflags -pkg-config guile-1.8 --libs +pkg-config guile-2.0 --cflags +pkg-config guile-2.0 --libs @end example To ease use of pkg-config with Autoconf, pkg-config comes with a @@ -71,7 +71,7 @@ accordingly, or prints an error and exits if Guile was not found: @findex PKG_CHECK_MODULES @example -PKG_CHECK_MODULES([GUILE], [guile-1.8]) +PKG_CHECK_MODULES([GUILE], [guile-2.0]) @end example Guile comes with additional Autoconf macros providing more information, diff --git a/doc/ref/compiler.texi b/doc/ref/compiler.texi index 27d8f79c8..0aea4e754 100644 --- a/doc/ref/compiler.texi +++ b/doc/ref/compiler.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Guile Reference Manual. -@c Copyright (C) 2008 +@c Copyright (C) 2008, 2009 @c Free Software Foundation, Inc. @c See the file guile.texi for copying conditions. @@ -17,14 +17,16 @@ This section aims to pay attention to the small man behind the curtain. @xref{Read/Load/Eval/Compile}, if you're lost and you just wanted to -know how to compile your .scm file. +know how to compile your @code{.scm} file. @menu * Compiler Tower:: * The Scheme Compiler:: -* GHIL:: +* Tree-IL:: * GLIL:: -* Object Code:: +* Assembly:: +* Bytecode and Objcode:: +* Writing New High-Level Languages:: * Extending the Compiler:: @end menu @@ -52,7 +54,7 @@ They are registered with the @code{define-language} form. @deffn {Scheme Syntax} define-language @ name title version reader printer @ -[parser=#f] [read-file=#f] [compilers='()] [evaluator=#f] +[parser=#f] [compilers='()] [decompilers='()] [evaluator=#f] Define a language. This syntax defines a @code{#} object, bound to @var{name} @@ -62,17 +64,14 @@ for Scheme: @example (define-language scheme - #:title "Guile Scheme" - #:version "0.5" - #:reader read - #:read-file read-file - #:compilers `((,ghil . ,compile-ghil)) - #:evaluator (lambda (x module) (primitive-eval x)) - #:printer write) + #:title "Guile Scheme" + #:version "0.5" + #:reader read + #:compilers `((tree-il . ,compile-tree-il)) + #:decompilers `((tree-il . ,decompile-tree-il)) + #:evaluator (lambda (x module) (primitive-eval x)) + #:printer write) @end example - -In this example, from @code{(language scheme spec)}, @code{read-file} -reads expressions from a port and wraps them in a @code{begin} block. @end deffn The interesting thing about having languages defined this way is that @@ -85,12 +84,12 @@ Guile Scheme interpreter 0.5 on Guile 1.9.0 Copyright (C) 2001-2008 Free Software Foundation, Inc. Enter `,help' for help. -scheme@@(guile-user)> ,language ghil -Guile High Intermediate Language (GHIL) interpreter 0.3 on Guile 1.9.0 +scheme@@(guile-user)> ,language tree-il +Tree Intermediate Language interpreter 1.0 on Guile 1.9.0 Copyright (C) 2001-2008 Free Software Foundation, Inc. Enter `,help' for help. -ghil@@(guile-user)> +tree-il@@(guile-user)> @end example Languages can be looked up by name, as they were above. @@ -128,17 +127,25 @@ The normal tower of languages when compiling Scheme goes like this: @itemize @item Scheme, which we know and love -@item Guile High Intermediate Language (GHIL) +@item Tree Intermediate Language (Tree-IL) @item Guile Low Intermediate Language (GLIL) -@item Object code +@item Assembly +@item Bytecode +@item Objcode @end itemize Object code may be serialized to disk directly, though it has a cookie -and version prepended to the front. But when compiling Scheme at -run time, you want a Scheme value, e.g. a compiled procedure. For this -reason, so as not to break the abstraction, Guile defines a fake -language, @code{value}. Compiling to @code{value} loads the object -code into a procedure, and wakes the sleeping giant. +and version prepended to the front. But when compiling Scheme at run +time, you want a Scheme value: for example, a compiled procedure. For +this reason, so as not to break the abstraction, Guile defines a fake +language at the bottom of the tower: + +@itemize +@item Value +@end itemize + +Compiling to @code{value} loads the object code into a procedure, and +wakes the sleeping giant. Perhaps this strangeness can be explained by example: @code{compile-file} defaults to compiling to object code, because it @@ -156,350 +163,287 @@ different worlds indefinitely, as shown by the following quine: @node The Scheme Compiler @subsection The Scheme Compiler -The job of the Scheme compiler is to expand all macros and to resolve -all symbols to lexical variables. Its target language, GHIL, is fairly -close to Scheme itself, so this process is not very complicated. +The job of the Scheme compiler is to expand all macros and all of +Scheme to its most primitive expressions. The definition of +``primitive'' is given by the inventory of constructs provided by +Tree-IL, the target language of the Scheme compiler: procedure +applications, conditionals, lexical references, etc. This is described +more fully in the next section. -The Scheme compiler is driven by a table of @dfn{translators}, -declared with the @code{define-scheme-translator} form, defined in the -module, @code{(language scheme compile-ghil)}. +The tricky and amusing thing about the Scheme-to-Tree-IL compiler is +that it is completely implemented by the macro expander. Since the +macro expander has to run over all of the source code already in order +to expand macros, it might as well do the analysis at the same time, +producing Tree-IL expressions directly. -@deffn {Scheme Syntax} define-scheme-translator head clause1 clause2... -The best documentation of this form is probably an example. Here is -the translator for @code{if}: +Because this compiler is actually the macro expander, it is +extensible. Any macro which the user writes becomes part of the +compiler. -@example -(define-scheme-translator if - ;; (if TEST THEN [ELSE]) - ((,test ,then) - (make-ghil-if e l (retrans test) (retrans then) (retrans '(begin)))) - ((,test ,then ,else) - (make-ghil-if e l (retrans test) (retrans then) (retrans else)))) -@end example +The Scheme-to-Tree-IL expander may be invoked using the generic +@code{compile} procedure: -The match syntax is from the @code{pmatch} macro, defined in -@code{(system base pmatch)}. The result of a clause should be a valid -GHIL value. If no clause matches, a syntax error is signalled. +@lisp +(compile '(+ 1 2) #:from 'scheme #:to 'tree-il) +@result{} + #< src: #f + proc: #< src: #f name: +> + args: (#< src: #f exp: 1> + #< src: #f exp: 2>)> +@end lisp -In the body of the clauses, the following bindings are introduced: -@itemize -@item @code{e}, the current environment -@item @code{l}, the current source location (or @code{#f}) -@item @code{retrans}, a procedure that may be called to compile -subexpressions -@end itemize +Or, since Tree-IL is so close to Scheme, it is often useful to expand +Scheme to Tree-IL, then translate back to Scheme. For that reason the +expander provides two interfaces. The former is equivalent to calling +@code{(sc-expand '(+ 1 2) 'c)}, where the @code{'c} is for +``compile''. With @code{'e} (the default), the result is translated +back to Scheme: -Note that translators are looked up by @emph{value}, not by name. That -is to say, the translator is keyed under the @emph{value} of -@code{if}, which normally prints as @code{#}. -@end deffn +@lisp +(sc-expand '(+ 1 2)) +@result{} (+ 1 2) +(sc-expand '(let ((x 10)) (* x x))) +@result{} (let ((x84 10)) (* x84 x84)) +@end lisp -Users can extend the compiler by defining new translators. -Additionally, some forms can be inlined directly to -instructions -- @xref{Inlined Scheme Instructions}, for a list. The -actual inliners are defined in @code{(language scheme inline)}: +The second example shows that as part of its job, the macro expander +renames lexically-bound variables. The original names are preserved +when compiling to Tree-IL, but can't be represented in Scheme: a +lexical binding only has one name. It is for this reason that the +@emph{native} output of the expander is @emph{not} Scheme. There's too +much information we would lose if we translated to Scheme directly: +lexical variable names, source locations, and module hygiene. -@deffn {Scheme Syntax} define-inline head arity1 result1 arity2 result2... -Defines an inliner for @code{head}. As in -@code{define-scheme-translator}, inliners are keyed by value and not -by name. +Note however that @code{sc-expand} does not have the same signature as +@code{compile-tree-il}. @code{compile-tree-il} is a small wrapper +around @code{sc-expand}, to make it conform to the general form of +compiler procedures in Guile's language tower. -Expressions are matched on their arities. For example: +Compiler procedures take three arguments: an expression, an +environment, and a keyword list of options. They return three values: +the compiled expression, the corresponding environment for the target +language, and a ``continuation environment''. The compiled expression +and environment will serve as input to the next language's compiler. +The ``continuation environment'' can be used to compile another +expression from the same source language within the same module. -@example -(define-inline eq? - (x y) (eq? x y)) -@end example +For example, you might compile the expression, @code{(define-module +(foo))}. This will result in a Tree-IL expression and environment. But +if you compiled a second expression, you would want to take into +account the compile-time effect of compiling the previous expression, +which puts the user in the @code{(foo)} module. That is purpose of the +``continuation environment''; you would pass it as the environment +when compiling the subsequent expression. -This inlines calls to the Scheme procedure, @code{eq?}, to the -instruction @code{eq?}. - -A more complicated example would be: - -@example -(define-inline + - () 0 - (x) x - (x y) (add x y) - (x y . rest) (add x (+ y . rest))) -@end example -@end deffn - -Compilers take two arguments, an expression and an environment, and -return two values as well: an expression in the target language, and -an environment suitable for the target language. The format of the -environment is language-dependent. - -For Scheme, an environment may be one of three things: +For Scheme, an environment may be one of two things: @itemize @item @code{#f}, in which case compilation is performed in the context -of the current module; -@item a module, which specifies the context of the compilation; or -@item a @dfn{compile environment}, which specifies lexical variables -as well. +of the current module; or +@item a module, which specifies the context of the compilation. @end itemize -The format of a compile environment for scheme is @code{(@var{module} -@var{lexicals} . @var{externals})}, though users are strongly -discouraged from constructing these environments themselves. Instead, -if you need this functionality -- as in GOOPS' dynamic method compiler --- capture an environment with @code{compile-time-environment}, then -pass that environment to @code{compile}. +@node Tree-IL +@subsection Tree-IL -@deffn {Scheme Procedure} compile-time-environment -A special function known to the compiler that, when compiled, will -return a representation of the lexical environment in place at compile -time. Useful for supporting some forms of dynamic compilation. Returns -@code{#f} if called from the interpreter. -@end deffn - -@node GHIL -@subsection GHIL - -Guile High Intermediate Language (GHIL) is a structured intermediate +Tree Intermediate Language (Tree-IL) is a structured intermediate language that is close in expressive power to Scheme. It is an expanded, pre-analyzed Scheme. -GHIL is ``structured'' in the sense that its representation is based -on records, not S-expressions. This gives a rigidity to the language -that ensures that compiling to a lower-level language only requires a -limited set of transformations. Practically speaking, consider the -GHIL type, @code{}, which has fields named @code{env}, -@code{loc}, and @code{exp}. Instances of this type are records created -via @code{make-ghil-quote}, and whose fields are accessed as -@code{ghil-quote-env}, @code{ghil-quote-loc}, and -@code{ghil-quote-exp}. There is also a predicate, @code{ghil-quote?}. -@xref{Records}, for more information on records. +Tree-IL is ``structured'' in the sense that its representation is +based on records, not S-expressions. This gives a rigidity to the +language that ensures that compiling to a lower-level language only +requires a limited set of transformations. Practically speaking, +consider the Tree-IL type, @code{}, which has two fields, +@code{src} and @code{exp}. Instances of this type are records created +via @code{make-const}, and whose fields are accessed as +@code{const-src}, and @code{const-exp}. There is also a predicate, +@code{const?}. @xref{Records}, for more information on records. -Expressions of GHIL name their environments explicitly, and all -variables are referenced by identity in addition to by name. -@code{(language ghil)} defines a number of routines to deal explicitly -with variables and environments: +@c alpha renaming -@deftp {Scheme Variable} [table='()] -A toplevel environment. The @var{table} holds all toplevel variables -that have been resolved in this environment. -@end deftp -@deftp {Scheme Variable} parent [table='()] [variables='()] -A lexical environment. @var{parent} will be the enclosing lexical -environment, or a toplevel environment. @var{table} holds an alist -mapping symbols to variables bound in this environment, while -@var{variables} holds a cumulative list of all variables ever defined -in this environment. +All Tree-IL types have a @code{src} slot, which holds source location +information for the expression. This information, if present, will be +residualized into the compiled object code, allowing backtraces to +show source information. The format of @code{src} is the same as that +returned by Guile's @code{source-properties} function. @xref{Source +Properties}, for more information. -Lexical environments correspond to procedures. Bindings introduced -e.g. by Scheme's @code{let} add to the bindings in a lexical -environment. An example of a case in which a variable might be in -@var{variables} but not in @var{table} would be a variable that is in -the same procedure, but is out of scope. -@end deftp -@deftp {Scheme Variable} env name kind [index=#f] -A variable. @var{kind} is one of @code{argument}, @code{local}, -@code{external}, @code{toplevel}, @code{public}, or @code{private}; -see the procedures below for more information. @var{index} is used in -compilation. -@end deftp - -@deffn {Scheme Procedure} ghil-var-is-bound? env sym -Recursively look up a variable named @var{sym} in @var{env}, and -return it or @code{#f} if none is found. -@end deffn -@deffn {Scheme Procedure} ghil-var-for-ref! env sym -Recursively look up a variable named @var{sym} in @var{env}, and -return it. If the symbol was not bound, return a new toplevel -variable. -@end deffn -@deffn {Scheme Procedure} ghil-var-for-set! env sym -Like @code{ghil-var-for-ref!}, except that the returned variable will -be marked as @code{external}. @xref{Variables and the VM}. -@end deffn -@deffn {Scheme Procedure} ghil-var-define! toplevel-env sym -Return an existing or new toplevel variable named @var{sym}. -@var{toplevel-env} must be a toplevel environment. -@end deffn -@deffn {Scheme Procedure} ghil-var-at-module! env modname sym interface? -Return a variable that will be resolved at run-time with respect to a -specific module named @var{modname}. If @var{interface?} is true, the -variable will be of type @code{public}, otherwise @code{private}. -@end deffn -@deffn {Scheme Procedure} call-with-ghil-environment env syms func -Bind @var{syms} to fresh variables within a new lexical environment -whose parent is @var{env}, and call @var{func} as @code{(@var{func} -@var{new-env} @var{new-vars})}. -@end deffn -@deffn {Scheme Procedure} call-with-ghil-bindings env syms func -Like @code{call-with-ghil-environment}, except the existing -environment @var{env} is re-used. For that reason, @var{func} is -invoked as @code{(@var{func} @var{new-vars})} -@end deffn - -In the aforementioned @code{} type, the @var{env} slot -holds a pointer to the environment in which the expression occurs. The -@var{loc} slot holds source location information, so that errors -corresponding to this expression can be mapped back to the initial -expression in the higher-level language, e.g. Scheme. @xref{Compiled -Procedures}, for more information on source location objects. - -GHIL also has a declarative serialization format, which makes writing -and reading it a tractable problem for the human mind. Since all GHIL -language constructs contain @code{env} and @code{loc} pointers, they -are left out of the serialization. (Serializing @code{env} structures -would be difficult, as they are often circular.) What is left is the -type of expression, and the remaining slots defined in the expression -type. - -For example, an S-expression representation of the @code{} -expression would be: +Although Tree-IL objects are represented internally using records, +there is also an equivalent S-expression external representation for +each kind of Tree-IL. For example, an the S-expression representation +of @code{#} expression would be: @example -(quote 3) +(const 3) @end example -It's deceptively like Scheme. The general rule is, for a type defined -as @code{ env loc @var{slot1} @var{slot2}...}, the -S-expression representation will be @code{(@var{foo} @var{slot1} -@var{slot2}...)}. Users may program with this format directly at the -REPL: +Users may program with this format directly at the REPL: @example -scheme@@(guile-user)> ,language ghil -Guile High Intermediate Language (GHIL) interpreter 0.3 on Guile 1.9.0 +scheme@@(guile-user)> ,language tree-il +Tree Intermediate Language interpreter 1.0 on Guile 1.9.0 Copyright (C) 2001-2008 Free Software Foundation, Inc. Enter `,help' for help. -ghil@@(guile-user)> (call (ref +) (quote 32) (quote 10)) +tree-il@@(guile-user)> (apply (primitive +) (const 32) (const 10)) @result{} 42 @end example -For convenience, some slots are serialized as rest arguments; those -are noted below. The other caveat is that variables are serialized as -their names only, and not their identities. +The @code{src} fields are left out of the external representation. -@deftp {Scheme Variable} env loc -The unspecified value. -@end deftp -@deftp {Scheme Variable} env loc exp -A quoted expression. +One may create Tree-IL objects from their external representations via +calling @code{parse-tree-il}, the reader for Tree-IL. If any source +information is attached to the input S-expression, it will be +propagated to the resulting Tree-IL expressions. This is probably the +easiest way to compile to Tree-IL: just make the appropriate external +representations in S-expression format, and let @code{parse-tree-il} +take care of the rest. -Note that unlike in Scheme, there are no self-quoting expressions; all -constants must come from @code{quote} expressions. +@deftp {Scheme Variable} src +@deftpx {External Representation} (void) +An empty expression. In practice, equivalent to Scheme's @code{(if #f +#f)}. @end deftp -@deftp {Scheme Variable} env loc exp -A quasiquoted expression. The expression is treated as a constant, -except for embedded @code{unquote} and @code{unquote-splicing} forms. +@deftp {Scheme Variable} src exp +@deftpx {External Representation} (const @var{exp}) +A constant. @end deftp -@deftp {Scheme Variable} env loc exp -Like Scheme's @code{unquote}; only valid within a quasiquote. +@deftp {Scheme Variable} src name +@deftpx {External Representation} (primitive @var{name}) +A reference to a ``primitive''. A primitive is a procedure that, when +compiled, may be open-coded. For example, @code{cons} is usually +recognized as a primitive, so that it compiles down to a single +instruction. + +Compilation of Tree-IL usually begins with a pass that resolves some +@code{} and @code{} expressions to +@code{} expressions. The actual compilation pass +has special cases for applications of certain primitives, like +@code{apply} or @code{cons}. @end deftp -@deftp {Scheme Variable} env loc exp -Like Scheme's @code{unquote-splicing}; only valid within a quasiquote. +@deftp {Scheme Variable} src name gensym +@deftpx {External Representation} (lexical @var{name} @var{gensym}) +A reference to a lexically-bound variable. The @var{name} is the +original name of the variable in the source program. @var{gensym} is a +unique identifier for this variable. @end deftp -@deftp {Scheme Variable} env loc var -A variable reference. Note that for purposes of serialization, -@var{var} is serialized as its name, as a symbol. +@deftp {Scheme Variable} src name gensym exp +@deftpx {External Representation} (set! (lexical @var{name} @var{gensym}) @var{exp}) +Sets a lexically-bound variable. @end deftp -@deftp {Scheme Variable} env loc var val -A variable mutation. @var{var} is serialized as a symbol. +@deftp {Scheme Variable} src mod name public? +@deftpx {External Representation} (@@ @var{mod} @var{name}) +@deftpx {External Representation} (@@@@ @var{mod} @var{name}) +A reference to a variable in a specific module. @var{mod} should be +the name of the module, e.g. @code{(guile-user)}. + +If @var{public?} is true, the variable named @var{name} will be looked +up in @var{mod}'s public interface, and serialized with @code{@@}; +otherwise it will be looked up among the module's private bindings, +and is serialized with @code{@@@@}. @end deftp -@deftp {Scheme Variable} env loc var val -A toplevel variable definition. See @code{ghil-var-define!}. +@deftp {Scheme Variable} src mod name public? exp +@deftpx {External Representation} (set! (@@ @var{mod} @var{name}) @var{exp}) +@deftpx {External Representation} (set! (@@@@ @var{mod} @var{name}) @var{exp}) +Sets a variable in a specific module. @end deftp -@deftp {Scheme Variable} env loc test then else +@deftp {Scheme Variable} src name +@deftpx {External Representation} (toplevel @var{name}) +References a variable from the current procedure's module. +@end deftp +@deftp {Scheme Variable} src name exp +@deftpx {External Representation} (set! (toplevel @var{name}) @var{exp}) +Sets a variable in the current procedure's module. +@end deftp +@deftp {Scheme Variable} src name exp +@deftpx {External Representation} (define (toplevel @var{name}) @var{exp}) +Defines a new top-level variable in the current procedure's module. +@end deftp +@deftp {Scheme Variable} src test then else +@deftpx {External Representation} (if @var{test} @var{then} @var{else}) A conditional. Note that @var{else} is not optional. @end deftp -@deftp {Scheme Variable} env loc . exps -Like Scheme's @code{and}. -@end deftp -@deftp {Scheme Variable} env loc . exps -Like Scheme's @code{or}. -@end deftp -@deftp {Scheme Variable} env loc . body -Like Scheme's @code{begin}. -@end deftp -@deftp {Scheme Variable} env loc vars exprs . body -Like a deconstructed @code{let}: each element of @var{vars} will be -bound to the corresponding GHIL expression in @var{exprs}. - -Note that for purposes of the serialization format, @var{exprs} are -evaluated before the new bindings are added to the environment. For -@code{letrec} semantics, there also exists a @code{bindrec} parse -flavor. This is useful for writing GHIL at the REPL, but the -serializer does not currently have the cleverness needed to determine -whether a @code{} has @code{let} or @code{letrec} -semantics, and thus only serializes @code{} as @code{bind}. -@end deftp -@deftp {Scheme Variable} env loc vars rest producer . body -Like Scheme's @code{receive} -- binds the values returned by -applying @code{producer}, which should be a thunk, to the -@code{lambda}-like bindings described by @var{vars} and @var{rest}. -@end deftp -@deftp {Scheme Variable} env loc vars rest meta . body -A closure. @var{vars} is the argument list, serialized as a list of -symbols. @var{rest} is a boolean, which is @code{#t} iff the last -argument is a rest argument. @var{meta} is an association list of -properties. The actual @var{body} should be a list of GHIL -expressions. -@end deftp -@deftp {Scheme Variable} env loc proc . args +@deftp {Scheme Variable} src proc args +@deftpx {External Representation} (apply @var{proc} . @var{args}) A procedure call. @end deftp -@deftp {Scheme Variable} env loc producer consumer -Like Scheme's @code{call-with-values}. +@deftp {Scheme Variable} src exps +@deftpx {External Representation} (begin . @var{exps}) +Like Scheme's @code{begin}. @end deftp -@deftp {Scheme Variable} env loc op . args -An inlined VM instruction. @var{op} should be the instruction name as -a symbol, and @var{args} should be its arguments, as GHIL expressions. +@deftp {Scheme Variable} src names vars meta body +@deftpx {External Representation} (lambda @var{names} @var{vars} @var{meta} @var{body}) +A closure. @var{names} is original binding form, as given in the +source code, which may be an improper list. @var{vars} are gensyms +corresponding to the @var{names}. @var{meta} is an association list of +properties. The actual @var{body} is a single Tree-IL expression. @end deftp -@deftp {Scheme Variable} env loc . values -Like Scheme's @code{values}. +@deftp {Scheme Variable} src names vars vals exp +@deftpx {External Representation} (let @var{names} @var{vars} @var{vals} @var{exp}) +Lexical binding, like Scheme's @code{let}. @var{names} are the +original binding names, @var{vars} are gensyms corresponding to the +@var{names}, and @var{vals} are Tree-IL expressions for the values. +@var{exp} is a single Tree-IL expression. @end deftp -@deftp {Scheme Variable} env loc . values -@var{values} are as in the Scheme expression, @code{(apply values . -@var{vals})}. -@end deftp -@deftp {Scheme Variable} env loc -Produces, at run-time, a reification of the environment at compile -time. Used in the implementation of Scheme's -@code{compile-time-environment}. +@deftp {Scheme Variable} src names vars vals exp +@deftpx {External Representation} (letrec @var{names} @var{vars} @var{vals} @var{exp}) +A version of @code{} that creates recursive bindings, like +Scheme's @code{letrec}. @end deftp -GHIL implements a compiler to GLIL that recursively traverses GHIL -expressions, writing out GLIL expressions into a linear list. The -compiler also keeps some state as to whether the current expression is -in tail context, and whether its value will be used in future -computations. This state allows the compiler not to emit code for -constant expressions that will not be used (e.g. docstrings), and to -perform tail calls when in tail position. +There are two Tree-IL constructs that are not normally produced by +higher-level compilers, but instead are generated during the +source-to-source optimization and analysis passes that the Tree-IL +compiler does. Users should not generate these expressions directly, +unless they feel very clever, as the default analysis pass will +generate them as necessary. -Just as the Scheme to GHIL compiler introduced new hidden state---the -environment---the GHIL to GLIL compiler introduces more state, the -stack. While not represented explicitly, the stack is present in the -compilation of each GHIL expression: compiling a GHIL expression -should leave the run-time value stack in the same state. For example, -if the intermediate value stack has two elements before evaluating an -@code{if} expression, it should have two elements after that -expression. +@deftp {Scheme Variable} src names vars exp body +@deftpx {External Representation} (let-values @var{names} @var{vars} @var{exp} @var{body}) +Like Scheme's @code{receive} -- binds the values returned by +evaluating @code{exp} to the @code{lambda}-like bindings described by +@var{vars}. That is to say, @var{vars} may be an improper list. + +@code{} is an optimization of @code{} of the +primitive, @code{call-with-values}. +@end deftp +@deftp {Scheme Variable} src names vars vals body +@deftpx {External Representation} (fix @var{names} @var{vars} @var{vals} @var{body}) +Like @code{}, but only for @var{vals} that are unset +@code{lambda} expressions. + +@code{fix} is an optimization of @code{letrec} (and @code{let}). +@end deftp + +Tree-IL implements a compiler to GLIL that recursively traverses +Tree-IL expressions, writing out GLIL expressions into a linear list. +The compiler also keeps some state as to whether the current +expression is in tail context, and whether its value will be used in +future computations. This state allows the compiler not to emit code +for constant expressions that will not be used (e.g. docstrings), and +to perform tail calls when in tail position. + +Most optimization, such as it currently is, is performed on Tree-IL +expressions as source-to-source transformations. There will be more +optimizations added in the future. Interested readers are encouraged to read the implementation in -@code{(language ghil compile-glil)} for more details. +@code{(language tree-il compile-glil)} for more details. @node GLIL @subsection GLIL Guile Low Intermediate Language (GLIL) is a structured intermediate -language whose expressions closely mirror the functionality of Guile's -VM instruction set. +language whose expressions more closely approximate Guile's VM +instruction set. Its expression types are defined in @code{(language +glil)}. -Its expression types are defined in @code{(language glil)}, and as -with GHIL, some of its fields parse as rest arguments. - -@deftp {Scheme Variable} nargs nrest nlocs nexts meta . body +@deftp {Scheme Variable} nargs nrest nlocs meta . body A unit of code that at run-time will correspond to a compiled -procedure. @var{nargs} @var{nrest} @var{nlocs}, and @var{nexts} -collectively define the program's arity; see @ref{Compiled -Procedures}, for more information. @var{meta} should be an alist of -properties, as in @code{}. @var{body} is a list of GLIL +procedure. @var{nargs} @var{nrest} and @var{nlocs} collectively define +the program's arity; see @ref{Compiled Procedures}, for more +information. @var{meta} should be an alist of properties, as in +Tree-IL's @code{}. @var{body} is an ordered list of GLIL expressions. @end deftp @deftp {Scheme Variable} . vars @@ -534,37 +478,34 @@ offset within a VM program. @end deftp @deftp {Scheme Variable} loc Records source information for the preceding expression. @var{loc} -should be a vector, @code{#(@var{line} @var{column} @var{filename})}. +should be an association list of containing @code{line} @code{column}, +and @code{filename} keys, e.g. as returned by +@code{source-properties}. @end deftp @deftp {Scheme Variable} -Pushes the unspecified value on the stack. +Pushes ``the unspecified value'' on the stack. @end deftp @deftp {Scheme Variable} obj Pushes a constant value onto the stack. @var{obj} must be a number, -string, symbol, keyword, boolean, character, or a pair or vector or -list thereof, or the empty list. +string, symbol, keyword, boolean, character, uniform array, the empty +list, or a pair or vector of constants. @end deftp -@deftp {Scheme Variable} op index -Accesses an argument on the stack. If @var{op} is @code{ref}, the -argument is pushed onto the stack; if it is @code{set}, the argument -is set from the top value on the stack, which is popped off. -@end deftp -@deftp {Scheme Variable} op index -Like @code{}, but for local variables. @xref{Stack -Layout}, for more information. -@end deftp -@deftp {Scheme Variable} op depth index -Accesses a heap-allocated variable, addressed by @var{depth}, the nth -enclosing environment, and @var{index}, the variable's position within -the environment. @var{op} is @code{ref} or @code{set}. +@deftp {Scheme Variable} local? boxed? op index +Accesses a lexically bound variable. If the variable is not +@var{local?} it is free. All variables may have @code{ref} and +@code{set} as their @var{op}. Boxed variables may also have the +@var{op}s @code{box}, @code{empty-box}, and @code{fix}, which +correspond in semantics to the VM instructions @code{box}, +@code{empty-box}, and @code{fix-closure}. @xref{Stack Layout}, for +more information. @end deftp @deftp {Scheme Variable} op name Accesses a toplevel variable. @var{op} may be @code{ref}, @code{set}, or @code{define}. @end deftp @deftp {Scheme Variable} op mod name public? -Accesses a variable within a specific module. See -@code{ghil-var-at-module!}, for more information. +Accesses a variable within a specific module. See Tree-IL's +@code{}, for more information. @end deftp @deftp {Scheme Variable} label Creates a new label. @var{label} can be any Scheme value, and should @@ -599,7 +540,7 @@ Guile Lowlevel Intermediate Language (GLIL) interpreter 0.3 on Guile 1.9.0 Copyright (C) 2001-2008 Free Software Foundation, Inc. Enter `,help' for help. -glil@@(guile-user)> (program 0 0 0 0 () (const 3) (call return 0)) +glil@@(guile-user)> (program 0 0 0 () (const 3) (call return 1)) @result{} 3 @end example @@ -607,23 +548,146 @@ Just as in all of Guile's compilers, an environment is passed to the GLIL-to-object code compiler, and one is returned as well, along with the object code. -@node Object Code -@subsection Object Code +@node Assembly +@subsection Assembly -Object code is the serialization of the raw instruction stream of a -program, ready for interpretation by the VM. Procedures related to -object code are defined in the @code{(system vm objcode)} module. +Assembly is an S-expression-based, human-readable representation of +the actual bytecodes that will be emitted for the VM. As such, it is a +useful intermediate language both for compilation and for +decompilation. + +Besides the fact that it is not a record-based language, assembly +differs from GLIL in four main ways: + +@itemize +@item Labels have been resolved to byte offsets in the program. +@item Constants inside procedures have either been expressed as inline +instructions or cached in object arrays. +@item Procedures with metadata (source location information, liveness +extents, procedure names, generic properties, etc) have had their +metadata serialized out to thunks. +@item All expressions correspond directly to VM instructions -- i.e., +there is no @code{} which can be a ref or a set. +@end itemize + +Assembly is isomorphic to the bytecode that it compiles to. You can +compile to bytecode, then decompile back to assembly, and you have the +same assembly code. + +The general form of assembly instructions is the following: + +@lisp +(@var{inst} @var{arg} ...) +@end lisp + +The @var{inst} names a VM instruction, and its @var{arg}s will be +embedded in the instruction stream. The easiest way to see assembly is +to play around with it at the REPL, as can be seen in this annotated +example: + +@example +scheme@@(guile-user)> (compile '(lambda (x) (+ x x)) #:to 'assembly) +(load-program 0 0 0 + () ; Labels + 70 ; Length + #f ; Metadata + (make-false) + (make-false) ; object table for the returned lambda + (nop) + (nop) ; Alignment. Since assembly has already resolved its labels + (nop) ; to offsets, and programs must be 8-byte aligned since their + (nop) ; object code is mmap'd directly to structures, assembly + (nop) ; has to have the alignment embedded in it. + (nop) + (load-program + 1 + 0 + () + 8 + (load-program 0 0 0 () 21 #f + (load-symbol "x") ; Name and liveness extent for @code{x}. + (make-false) + (make-int8:0) ; Some instruction+arg combinations + (make-int8:0) ; have abbreviations. + (make-int8 6) + (list 0 5) + (list 0 1) + (make-eol) + (list 0 2) + (return)) + ; And here, the actual code. + (local-ref 0) + (local-ref 0) + (add) + (return) + (nop) + (nop)) + ; Return our new procedure. + (return)) +@end example + +Of course you can switch the REPL to assembly and enter in assembly +S-expressions directly, like with other languages, though it is more +difficult, given that the length fields have to be correct. + +@node Bytecode and Objcode +@subsection Bytecode and Objcode + +Finally, the raw bytes. There are actually two different ``languages'' +here, corresponding to two different ways to represent the bytes. + +``Bytecode'' represents code as uniform byte vectors, useful for +structuring and destructuring code on the Scheme level. Bytecode is +the next step down from assembly: + +@example +scheme@@(guile-user)> (compile '(+ 32 10) #:to 'assembly) +@result{} (load-program 0 0 0 () 6 #f + (make-int8 32) (make-int8 10) (add) (return)) +scheme@@(guile-user)> (compile '(+ 32 10) #:to 'bytecode) +@result{} #u8(0 0 0 0 6 0 0 0 0 0 0 0 0 0 0 0 10 32 10 10 120 52) +@end example + +``Objcode'' is bytecode, but mapped directly to a C structure, +@code{struct scm_objcode}: + +@example +struct scm_objcode @{ + scm_t_uint8 nargs; + scm_t_uint8 nrest; + scm_t_uint16 nlocs; + scm_t_uint32 len; + scm_t_uint32 metalen; + scm_t_uint8 base[0]; +@}; +@end example + +As one might imagine, objcode imposes a minimum length on the +bytecode. Also, the multibyte fields are in native endianness, which +makes objcode (and bytecode) system-dependent. Indeed, in the short +example above, all but the last 6 bytes were the program's header. + +Objcode also has a couple of important efficiency hacks. First, +objcode may be mapped directly from disk, allowing compiled code to be +loaded quickly, often from the system's disk cache, and shared among +multiple processes. Secondly, objcode may be embedded in other +objcode, allowing procedures to have the text of other procedures +inlined into their bodies, without the need for separate allocation of +the code. Of course, the objcode object itself does need to be +allocated. + +Procedures related to objcode are defined in the @code{(system vm +objcode)} module. @deffn {Scheme Procedure} objcode? obj @deffnx {C Function} scm_objcode_p (obj) Returns @code{#f} iff @var{obj} is object code, @code{#f} otherwise. @end deffn -@deffn {Scheme Procedure} bytecode->objcode bytecode nlocs nexts -@deffnx {C Function} scm_bytecode_to_objcode (bytecode, nlocs, nexts) +@deffn {Scheme Procedure} bytecode->objcode bytecode +@deffnx {C Function} scm_bytecode_to_objcode (bytecode,) Makes a bytecode object from @var{bytecode}, which should be a -@code{u8vector}. @var{nlocs} and @var{nexts} denote the number of -stack and heap variables to reserve when this objcode is executed. +@code{u8vector}. @end deffn @deffn {Scheme Variable} load-objcode file @@ -631,21 +695,28 @@ stack and heap variables to reserve when this objcode is executed. Load object code from a file named @var{file}. The file will be mapped into memory via @code{mmap}, so this is a very fast operation. -On disk, object code has an eight-byte cookie prepended to it, so that -we will not execute arbitrary garbage. In addition, two more bytes are -reserved for @var{nlocs} and @var{nexts}. +On disk, object code has an sixteen-byte cookie prepended to it, to +prevent accidental loading of arbitrary garbage. +@end deffn + +@deffn {Scheme Variable} write-objcode objcode file +@deffnx {C Function} scm_write_objcode (objcode) +Write object code out to a file, prepending the eight-byte cookie. @end deffn @deffn {Scheme Variable} objcode->u8vector objcode @deffnx {C Function} scm_objcode_to_u8vector (objcode) -Copy object code out to a @code{u8vector} for analysis by Scheme. The -ten-byte header is included. +Copy object code out to a @code{u8vector} for analysis by Scheme. @end deffn -@deffn {Scheme Variable} objcode->program objcode [external='()] -@deffnx {C Function} scm_objcode_to_program (objcode, external) +The following procedure is actually in @code{(system vm program)}, but +we'll mention it here: + +@deffn {Scheme Variable} make-program objcode objtable [free-vars=#f] +@deffnx {C Function} scm_make_program (objcode, objtable, free_vars) Load up object code into a Scheme program. The resulting program will -be a thunk that captures closure variables from @var{external}. +have @var{objtable} as its object table, which should be a vector or +@code{#f}, and will capture the free variables from @var{free-vars}. @end deffn Object code from a file may be disassembled at the REPL via the @@ -659,12 +730,25 @@ respect to the compilation environment. Normally the environment propagates through the compiler transparently, but users may specify the compilation environment manually as well: -@deffn {Scheme Procedure} make-objcode-env module externals +@deffn {Scheme Procedure} make-objcode-env module free-vars Make an object code environment. @var{module} should be a Scheme -module, and @var{externals} should be a list of external variables. +module, and @var{free-vars} should be a vector of free variables. @code{#f} is also a valid object code environment. @end deffn +@node Writing New High-Level Languages +@subsection Writing New High-Level Languages + +In order to integrate a new language @var{lang} into Guile's compiler +system, one has to create the module @code{(language @var{lang} spec)} +containing the language definition and referencing the parser, +compiler and other routines processing it. The module hierarchy in +@code{(language brainfuck)} defines a very basic Brainfuck +implementation meant to serve as easy-to-understand example on how to +do this. See for instance @url{http://en.wikipedia.org/wiki/Brainfuck} +for more information about the Brainfuck language itself. + + @node Extending the Compiler @subsection Extending the Compiler @@ -687,12 +771,14 @@ procedure is called a certain number of times. The name of the game is a profiling-based harvest of the low-hanging fruit, running programs of interest under a system-level profiler and determining which improvements would give the most bang for the buck. -There are many well-known efficiency hacks in the literature: Dybvig's -letrec optimization, individual boxing of heap-allocated values (and -then store the boxes on the stack directory), optimized case-lambda -expressions, stack underflow and overflow handlers, etc. Highly -recommended papers: Dybvig's HOCS, Ghuloum's compiler paper. +It's really getting to the point though that native compilation is the +next step. The compiler also needs help at the top end, enhancing the Scheme that -it knows to also understand R6RS, and adding new high-level compilers: -Emacs Lisp, Lua, JavaScript... +it knows to also understand R6RS, and adding new high-level compilers. +We have JavaScript and Emacs Lisp mostly complete, but they could use +some love; Lua would be nice as well, butq whatever language it is +that strikes your fancy would be welcome too. + +Compilers are for hacking, not for admiring or for complaining about. +Get to it! diff --git a/doc/ref/intro.texi b/doc/ref/intro.texi index a31fe30f8..b0c4c1263 100644 --- a/doc/ref/intro.texi +++ b/doc/ref/intro.texi @@ -470,12 +470,12 @@ You can get the version number by invoking the command @example $ guile --version -Guile 1.4.1 -Copyright (c) 1995, 1996, 1997, 2000, 2006 Free Software Foundation -Guile may be distributed under the terms of the GNU General Public License; -certain other uses are permitted as well. For details, see the file -`COPYING', which is included in the Guile distribution. -There is no warranty, to the extent permitted by law. +Guile 1.9.0 +Copyright (c) 1995, 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation +Guile may be distributed under the terms of the GNU Lesser General +Public Licence. For details, see the files `COPYING.LESSER' and +`COPYING', which are included in the Guile distribution. There is no +warranty, to the extent permitted by law. @end example @item diff --git a/doc/ref/libguile-concepts.texi b/doc/ref/libguile-concepts.texi index 8979f0cd6..15d54f531 100644 --- a/doc/ref/libguile-concepts.texi +++ b/doc/ref/libguile-concepts.texi @@ -182,7 +182,7 @@ As explained above, the @code{SCM} type can represent all Scheme values. Some values fit entirely into a @code{SCM} value (such as small integers), but other values require additional storage in the heap (such as strings and vectors). This additional storage is managed -automatically by Guile. You don't need to explicitely deallocate it +automatically by Guile. You don't need to explicitly deallocate it when a @code{SCM} value is no longer used. Two things must be guaranteed so that Guile is able to manage the diff --git a/doc/ref/posix.texi b/doc/ref/posix.texi index cb19a7af8..2d64919a5 100644 --- a/doc/ref/posix.texi +++ b/doc/ref/posix.texi @@ -1909,10 +1909,6 @@ for termination, not stopping. If a signal occurs while in a system call, deliver the signal then restart the system call (as opposed to returning an @code{EINTR} error from that call). - -Guile always enables this flag where available, no matter what -@var{flags} are specified. This avoids spurious error returns in low -level operations. @end defvar The return value is a pair with information about the old handler as diff --git a/doc/ref/preface.texi b/doc/ref/preface.texi index d6de77440..7fa85811b 100644 --- a/doc/ref/preface.texi +++ b/doc/ref/preface.texi @@ -159,12 +159,12 @@ person would want to do. @itemize @bullet @item The Guile library (libguile) and supporting files are published under -the terms of the GNU Lesser General Public License version 2.1. See -the file @file{COPYING.LIB}. +the terms of the GNU Lesser General Public License version 3 or later. +See the files @file{COPYING.LESSER} and @file{COPYING}. @item The Guile readline module is published under the terms of the GNU -General Public License version 2. See the file @file{COPYING}. +General Public License version 3 or later. See the file @file{COPYING}. @item The manual you're now reading is published under the terms of the GNU diff --git a/doc/ref/srfi-modules.texi b/doc/ref/srfi-modules.texi index 1fa50b209..7c107e710 100644 --- a/doc/ref/srfi-modules.texi +++ b/doc/ref/srfi-modules.texi @@ -47,6 +47,7 @@ get the relevant SRFI documents from the SRFI home page * SRFI-61:: A more general `cond' clause * SRFI-69:: Basic hash tables. * SRFI-88:: Keyword objects. +* SRFI-98:: Accessing environment variables. @end menu @@ -3608,6 +3609,25 @@ Return the keyword object whose name is @var{str}. @end example @end deffn +@node SRFI-98 +@subsection SRFI-98 Accessing environment variables. +@cindex SRFI-98 +@cindex environment variables + +This is a portable wrapper around Guile's built-in support for +interacting with the current environment, @xref{Runtime Environment}. + +@deffn {Scheme Procedure} get-environment-variable name +Returns a string containing the value of the environment variable +given by the string @code{name}, or @code{#f} if the named +environment variable is not found. This is equivalent to +@code{(getenv name)}. +@end deffn + +@deffn {Scheme Procedure} get-environment-variables +Returns the names and values of all the environment variables as an +association list in which both the keys and the values are strings. +@end deffn @c srfi-modules.texi ends here diff --git a/doc/ref/vm.texi b/doc/ref/vm.texi index 042645200..59798d881 100644 --- a/doc/ref/vm.texi +++ b/doc/ref/vm.texi @@ -13,8 +13,8 @@ procedures can call each other as they please. The difference is that the compiler creates and interprets bytecode for a custom virtual machine, instead of interpreting the -S-expressions directly. Running compiled code is faster than running -interpreted code. +S-expressions directly. Loading and running compiled code is faster +than loading and running source code. The virtual machine that does the bytecode interpretation is a part of Guile itself. This section describes the nature of Guile's virtual @@ -111,7 +111,7 @@ The registers that a VM has are as follows: In other architectures, the instruction pointer is sometimes called the ``program counter'' (pc). This set of registers is pretty typical for stack machines; their exact meanings in the context of Guile's VM -is described in the next section. +are described in the next section. A virtual machine executes by loading a compiled procedure, and executing the object code associated with that procedure. Of course, @@ -119,19 +119,22 @@ that procedure may call other procedures, tail-call others, ad infinitum---indeed, within a guile whose modules have all been compiled to object code, one might never leave the virtual machine. -@c wingo: I wish the following were true, but currently we just use -@c the one engine. This kind of thing is possible tho. +@c wingo: The following is true, but I don't know in what context to +@c describe it. A documentation FIXME. @c A VM may have one of three engines: reckless, regular, or debugging. @c Reckless engine is fastest but dangerous. Regular engine is normally @c fail-safe and reasonably fast. Debugging engine is safest and @c functional but very slow. +@c (Actually we have just a regular and a debugging engine; normally +@c we use the latter, it's almost as fast as the ``regular'' engine.) + @node Stack Layout @subsection Stack Layout While not strictly necessary to understand how to work with the VM, it -is instructive and sometimes entertaining to consider the struture of +is instructive and sometimes entertaining to consider the structure of the VM stack. Logically speaking, a VM stack is composed of ``frames''. Each frame @@ -156,12 +159,11 @@ The structure of the fixed part of an application frame is as follows: @example Stack - | | <- fp + bp->nargs + bp->nlocs + 4 + | | <- fp + bp->nargs + bp->nlocs + 3 +------------------+ = SCM_FRAME_UPPER_ADDRESS (fp) | Return address | | MV return address| - | Dynamic link | - | External link | <- fp + bp->nargs + bp->nlocs + | Dynamic link | <- fp + bp->nargs + bp->nlocs | Local variable 1 | = SCM_FRAME_DATA_ADDRESS (fp) | Local variable 0 | <- fp + bp->nargs | Argument 1 | @@ -174,7 +176,7 @@ The structure of the fixed part of an application frame is as follows: In the above drawing, the stack grows upward. The intermediate values stored in the application of this frame are stored above @code{SCM_FRAME_UPPER_ADDRESS (fp)}. @code{bp} refers to the -@code{struct scm_program*} data associated with the program at +@code{struct scm_objcode} data associated with the program at @code{fp - 1}. @code{nargs} and @code{nlocs} are properties of the compiled procedure, which will be discussed later. @@ -198,25 +200,17 @@ values being returned. @item Dynamic link This is the @code{fp} in effect before this program was applied. In effect, this and the return address are the registers that are always -``saved''. - -@item External link -This field is a reference to the list of heap-allocated variables -associated with this frame. For a discussion of heap versus stack -allocation, @xref{Variables and the VM}. +``saved''. The dynamic link links the current frame to the previous +frame; computing a stack trace involves traversing these frames. @item Local variable @var{n} -Lambda-local variables that are allocated on the stack are all -allocated as part of the frame. This makes access to non-captured, -non-mutated variables very cheap. +Lambda-local variables that are all allocated as part of the frame. +This makes access to variables very cheap. @item Argument @var{n} The calling convention of the VM requires arguments of a function -application to be pushed on the stack, and here they are. Normally -references to arguments dispatch to these locations on the stack. -However if an argument has to be stored on the heap, it will be copied -from its initial value here onto a location in the heap, and -thereafter only referenced on the heap. +application to be pushed on the stack, and here they are. References +to arguments dispatch to these locations on the stack. @item Program This is the program being applied. For more information on how @@ -226,40 +220,51 @@ programs are implemented, @xref{VM Programs}. @node Variables and the VM @subsection Variables and the VM -Let's think about the following Scheme code as an example: +Consider the following Scheme code as an example: @example (define (foo a) (lambda (b) (list foo a b))) @end example -Within the lambda expression, "foo" is a top-level variable, "a" is a -lexically captured variable, and "b" is a local variable. +Within the lambda expression, @code{foo} is a top-level variable, @code{a} is a +lexically captured variable, and @code{b} is a local variable. -That is to say: @code{b} may safely be allocated on the stack, as -there is no enclosed procedure that references it, nor is it ever -mutated. +Another way to refer to @code{a} and @code{b} is to say that @code{a} +is a ``free'' variable, since it is not defined within the lambda, and +@code{b} is a ``bound'' variable. These are the terms used in the +@dfn{lambda calculus}, a mathematical notation for describing +functions. The lambda calculus is useful because it allows one to +prove statements about functions. It is especially good at describing +scope relations, and it is for that reason that we mention it here. -@code{a}, on the other hand, is referenced by an enclosed procedure, -that of the lambda. Thus it must be allocated on the heap, as it may -(and will) outlive the dynamic extent of the invocation of @code{foo}. +Guile allocates all variables on the stack. When a lexically enclosed +procedure with free variables---a @dfn{closure}---is created, it +copies those variables its free variable vector. References to free +variables are then redirected through the free variable vector. -@code{foo} is a toplevel variable, as mandated by Scheme's semantics: +If a variable is ever @code{set!}, however, it will need to be +heap-allocated instead of stack-allocated, so that different closures +that capture the same variable can see the same value. Also, this +allows continuations to capture a reference to the variable, instead +of to its value at one point in time. For these reasons, @code{set!} +variables are allocated in ``boxes''---actually, in variable cells. +@xref{Variables}, for more information. References to @code{set!} +variables are indirected through the boxes. -@example - (define proc (foo 'bar)) ; assuming prev. definition of @code{foo} - (define foo 42) ; redefinition - (proc 'baz) - @result{} (42 bar baz) -@end example +Thus perhaps counterintuitively, what would seem ``closer to the +metal'', viz @code{set!}, actually forces an extra memory allocation +and indirection. -Note that variables that are mutated (via @code{set!}) must be -allocated on the heap, even if they are local variables. This is -because any called subprocedure might capture the continuation, which -would need to capture locations instead of values. Thus perhaps -counterintuitively, what would seem ``closer to the metal'', viz -@code{set!}, actually forces heap allocation instead of stack -allocation. +Going back to our example, @code{b} may be allocated on the stack, as +it is never mutated. + +@code{a} may also be allocated on the stack, as it too is never +mutated. Within the enclosed lambda, its value will be copied into +(and referenced from) the free variables vector. + +@code{foo} is a top-level variable, because @code{foo} is not +lexically bound in this example. @node VM Programs @subsection Compiled Procedures are VM Programs @@ -276,6 +281,7 @@ You can pick apart these pieces with the accessors in @code{(system vm program)}. @xref{Compiled Procedures}, for a full API reference. @cindex object table +@cindex object array The object array of a compiled procedure, also known as the @dfn{object table}, holds all Scheme objects whose values are known not to change across invocations of the procedure: constant strings, @@ -293,38 +299,33 @@ instruction, which uses the object vector, and are almost as fast as local variable references. We can see how these concepts tie together by disassembling the -@code{foo} function to see what is going on: +@code{foo} function we defined earlier to see what is going on: @smallexample scheme@@(guile-user)> (define (foo a) (lambda (b) (list foo a b))) scheme@@(guile-user)> ,x foo Disassembly of #: -Bytecode: - - 0 (local-ref 0) ;; `a' (arg) - 2 (external-set 0) ;; `a' (arg) - 4 (object-ref 0) ;; # - 6 (make-closure) at (unknown file):0:16 - 7 (return) + 0 (object-ref 1) ;; #:0:16 (b)> + 2 (local-ref 0) ;; `a' (arg) + 4 (vector 0 1) ;; 1 element + 7 (make-closure) + 8 (return) ---------------------------------------- -Disassembly of #: +Disassembly of #:0:16 (b)>: -Bytecode: - - 0 (toplevel-ref 0) ;; `list' - 2 (toplevel-ref 1) ;; `foo' - 4 (external-ref 0) ;; (closure variable) - 6 (local-ref 0) ;; `b' (arg) - 8 (goto/args 3) at (unknown file):0:28 + 0 (toplevel-ref 1) ;; `foo' + 2 (free-ref 0) ;; (closure variable) + 4 (local-ref 0) ;; `b' (arg) + 6 (list 0 3) ;; 3 elements at (unknown file):0:28 + 9 (return) @end smallexample -At @code{ip} 0 and 2, we do the copy from argument to heap for -@code{a}. @code{Ip} 4 loads up the compiled lambda, and then at -@code{ip} 6 we make a closure---binding code (from the compiled -lambda) with data (the heap-allocated variables). Finally we return -the closure. +At @code{ip} 0, we load up the compiled lambda. @code{Ip} 2 and 4 +create the free variables vector, and @code{ip} 7 makes the +closure---binding code (from the compiled lambda) with data (the +free-variable vector). Finally we return the closure. The second stanza disassembles the compiled lambda. Toplevel variables are resolved relative to the module that was current when the @@ -336,13 +337,14 @@ Control Instructions}, for more details. Then we see a reference to an external variable, corresponding to @code{a}. The disassembler doesn't have enough information to give a name to that variable, so it just marks it as being a ``closure -variable''. Finally we see the reference to @code{b}, then a tail call -(@code{goto/args}) with three arguments. +variable''. Finally we see the reference to @code{b}, then the +@code{list} opcode, an inline implementation of the @code{list} scheme +routine. @node Instruction Set @subsection Instruction Set -There are about 100 instructions in Guile's virtual machine. These +There are about 150 instructions in Guile's virtual machine. These instructions represent atomic units of a program's execution. Ideally, they perform one task without conditional branches, then dispatch to the next instruction in the stream. @@ -365,7 +367,8 @@ their own test-and-branch instructions: @end example In addition, some Scheme primitives have their own inline -implementations, e.g. @code{cons}. +implementations, e.g. @code{cons}, and @code{list}, as we saw in the +previous section. So Guile's instruction set is a @emph{complete} instruction set, in that it provides the instructions that are suited to the problem, and @@ -381,16 +384,22 @@ instructions. More instructions may be added over time. * Miscellaneous Instructions:: * Inlined Scheme Instructions:: * Inlined Mathematical Instructions:: +* Inlined Bytevector Instructions:: @end menu @node Environment Control Instructions @subsubsection Environment Control Instructions These instructions access and mutate the environment of a compiled -procedure---the local bindings, the ``external'' bindings, and the +procedure---the local bindings, the free (captured) bindings, and the toplevel bindings. +Some of these instructions have @code{long-} variants, the difference +being that they take 16-bit arguments, encoded in big-endianness, +instead of the normal 8-bit range. + @deffn Instruction local-ref index +@deffnx Instruction long-local-ref index Push onto the stack the value of the local variable located at @var{index} within the current stack frame. @@ -400,34 +409,65 @@ arguments. @end deffn @deffn Instruction local-set index +@deffnx Instruction long-local-ref index Pop the Scheme object located on top of the stack and make it the new value of the local variable located at @var{index} within the current stack frame. @end deffn -@deffn Instruction external-ref index -Push the value of the closure variable located at position -@var{index} within the program's list of external variables. +@deffn Instruction free-ref index +Push the value of the captured variable located at position +@var{index} within the program's vector of captured variables. @end deffn -@deffn Instruction external-set index -Pop the Scheme object located on top of the stack and make it the new -value of the closure variable located at @var{index} within the -program's list of external variables. +@deffn Instruction free-boxed-ref index +@deffnx Instruction free-boxed-set index +Get or set a boxed free variable. Note that there is no free-set +instruction, as variables that are @code{set!} must be boxed. + +These instructions assume that the value at position @var{index} in +the free variables vector is a variable. @end deffn -The external variable lookup algorithm should probably be made more -efficient in the future via addressing by frame and index. Currently, -external variables are all consed onto a list, which results in O(N) -lookup time. +@deffn Instruction make-closure +Pop a vector and a program object off the stack, in that order, and +push a new program object with the given free variables vector. The +new program object shares state with the original program. -@deffn Instruction externals -Pushes the current list of external variables onto the stack. This -instruction is used in the implementation of -@code{compile-time-environment}. @xref{The Scheme Compiler}. +At the time of this writing, the space overhead of closures is 4 words +per closure. +@end deffn + +@deffn Instruction fix-closure index +Pop a vector off the stack, and set it as the @var{index}th local +variable's free variable vector. The @var{index}th local variable is +assumed to be a procedure. + +This instruction is part of a hack for allocating mutually recursive +procedures. The hack is to first perform a @code{local-set} for all of +the recursive procedures, then fix up the procedures' free variable +bindings in place. This allows most @code{letrec}-bound procedures to +be allocated unboxed on the stack. + +One could of course do a @code{local-ref}, then @code{make-closure}, +then @code{local-set}, but this macroinstruction helps to speed up the +common case. +@end deffn + +@deffn Instruction box index +Pop a value off the stack, and set the @var{index}nth local variable +to a box containing that value. A shortcut for @code{make-variable} +then @code{local-set}, used when binding boxed variables. +@end deffn + +@deffn Instruction empty-box index +Set the @var{indext}h local variable to a box containing a variable +whose value is unbound. Used when compiling some @code{letrec} +expressions. @end deffn @deffn Instruction toplevel-ref index +@deffnx Instruction long-toplevel-ref index Push the value of the toplevel binding whose location is stored in at position @var{index} in the object table. @@ -440,11 +480,11 @@ created. Alternately, the lookup may be performed relative to a particular module, determined at compile-time (e.g. via @code{@@} or @code{@@@@}). In that case, the cell in the object table holds a list: -@code{(@var{modname} @var{sym} @var{interface?})}. The symbol -@var{sym} will be looked up in the module named @var{modname} (a list -of symbols). The lookup will be performed against the module's public -interface, unless @var{interface?} is @code{#f}, which it is for -example when compiling @code{@@@@}. +@code{(@var{modname} @var{sym} @var{public?})}. The symbol @var{sym} +will be looked up in the module named @var{modname} (a list of +symbols). The lookup will be performed against the module's public +interface, unless @var{public?} is @code{#f}, which it is for example +when compiling @code{@@@@}. In any case, if the symbol is unbound, an error is signalled. Otherwise the initial form is replaced with the looked-up variable, an @@ -455,13 +495,20 @@ variable has been successfully resolved. This instruction pushes the value of the variable onto the stack. @end deffn -@deffn Instruction toplevel-ref index +@deffn Instruction toplevel-set index +@deffnx Instruction long-toplevel-set index Pop a value off the stack, and set it as the value of the toplevel variable stored at @var{index} in the object table. If the variable has not yet been looked up, we do the lookup as in @code{toplevel-ref}. @end deffn +@deffn Instruction define +Pop a symbol and a value from the stack, in that order. Look up its +binding in the current toplevel environment, creating the binding if +necessary. Set the variable to the value. +@end deffn + @deffn Instruction link-now Pop a value, @var{x}, from the stack. Look up the binding for @var{x}, according to the rules for @code{toplevel-ref}, and push that variable @@ -481,8 +528,15 @@ Pop off two objects from the stack, a variable and a value, and set the variable to the value. @end deffn +@deffn Instruction make-variable +Replace the top object on the stack with a variable containing it. +Used in some circumstances when compiling @code{letrec} expressions. +@end deffn + @deffn Instruction object-ref n -Push @var{n}th value from the current program's object vector. +@deffnx Instruction long-object-ref n +Push @var{n}th value from the current program's object vector. The +``long'' variant has a 16-bit index instead of an 8-bit index. @end deffn @node Branch Instructions @@ -502,7 +556,10 @@ the one to which the instruction pointer points). @end itemize Note that the offset passed to the instruction is encoded on two 8-bit -integers which are then combined by the VM as one 16-bit integer. +integers which are then combined by the VM as one 16-bit integer. Note +also that jump targets in Guile are aligned on 8-byte boundaries, and +that the offset refers to the @var{n}th 8-byte boundary, effectively +giving Guile a 19-bit relative address space. @deffn Instruction br offset Jump to @var{offset}. @@ -546,81 +603,47 @@ the instruction pointer to the next VM instruction. All of these loading instructions have a @code{length} parameter, indicating the size of the embedded data, in bytes. The length itself -may be encoded in 1, 2, or 4 bytes. +is encoded in 3 bytes. -@deffn Instruction load-integer length -@deffnx Instruction load-unsigned-integer length -Load a 32-bit integer (respectively unsigned integer) from the -instruction stream. -@end deffn @deffn Instruction load-number length Load an arbitrary number from the instruction stream. The number is embedded in the stream as a string. @end deffn @deffn Instruction load-string length -Load a string from the instruction stream. +Load a string from the instruction stream. The string is assumed to be +encoded in the ``latin1'' locale. +@end deffn +@deffn Instruction load-wide-string length +Load a UTF-32 string from the instruction stream. @var{length} is the +length in bytes, not in codepoints @end deffn @deffn Instruction load-symbol length -Load a symbol from the instruction stream. +Load a symbol from the instruction stream. The symbol is assumed to be +encoded in the ``latin1'' locale. Symbols backed by wide strings may +be loaded via @code{load-wide-string} then @code{make-symbol}. @end deffn -@deffn Instruction load-keyword length -Load a keyword from the instruction stream. +@deffn Instruction load-array length +Load a uniform array from the instruction stream. The shape and type +of the array are popped off the stack, in that order. @end deffn -@deffn Instruction define length -Load a symbol from the instruction stream, and look up its binding in -the current toplevel environment, creating the binding if necessary. -Push the variable corresponding to the binding. -@end deffn - -@deffn Instruction load-program length +@deffn Instruction load-program Load bytecode from the instruction stream, and push a compiled -procedure. This instruction pops the following values from the stack: +procedure. -@itemize -@item Optionally, a thunk, which when called should return metadata -associated with this program---for example its name, the names of its -arguments, its documentation string, debugging information, etc. +This instruction pops one value from the stack: the program's object +table, as a vector, or @code{#f} in the case that the program has no +object table. A program that does not reference toplevel bindings and +does not use @code{object-ref} does not need an object table. -Normally, this thunk its itself a compiled procedure (with no -metadata). Metadata is represented this way so that the initial load -of a procedure is fast: the VM just mmap's the thunk and goes. The -symbols and pairs associated with the metadata are only created if the -user asks for them. +This instruction is unlike the rest of the loading instructions, +because instead of parsing its data, it directly maps the instruction +stream onto a C structure, @code{struct scm_objcode}. @xref{Bytecode +and Objcode}, for more information. -For information on the format of the thunk's return value, -@xref{Compiled Procedures}. -@item Optionally, the program's object table, as a vector. - -A program that does not reference toplevel bindings and does not use -@code{object-ref} does not need an object table. -@item Finally, either one immediate integer or four immediate integers -representing the arity of the program. - -In the four-fixnum case, the values are respectively the number of -arguments taken by the function (@var{nargs}), the number of @dfn{rest -arguments} (@var{nrest}, 0 or 1), the number of local variables -(@var{nlocs}) and the number of external variables (@var{nexts}) -(@pxref{Environment Control Instructions}). - -The common single-fixnum case represents all of these values within a -16-bit bitmask. -@end itemize - -The resulting compiled procedure will not have any ``external'' -variables captured, so it will be loaded only once but may be used -many times to create closures. -@end deffn - -Finally, while this instruction is not strictly a ``loading'' -instruction, it's useful to wind up the @code{load-program} discussion -here: - -@deffn Instruction make-closure -Pop the program object from the stack, capture the current set of -``external'' variables, and assign those external variables to a copy -of the program. Push the new program object, which shares state with -the original program. Also captures the current module. +The resulting compiled procedure will not have any free variables +captured, so it may be loaded only once but used many times to create +closures. @end deffn @node Procedural Instructions @@ -640,22 +663,24 @@ set to the returned value. @deffn Instruction call nargs Call the procedure located at @code{sp[-nargs]} with the @var{nargs} -arguments located from @code{sp[0]} to @code{sp[-nargs + 1]}. +arguments located from @code{sp[-nargs + 1]} to @code{sp[0]}. + +For compiled procedures, this instruction sets up a new stack frame, +as described in @ref{Stack Layout}, and then dispatches to the first +instruction in the called procedure, relying on the called procedure +to return one value to the newly-created continuation. Because the new +frame pointer will point to sp[-nargs + 1], the arguments don't have +to be shuffled around -- they are already in place. For non-compiled procedures (continuations, primitives, and interpreted procedures), @code{call} will pop the procedure and arguments off the stack, and push the result of calling @code{scm_apply}. - -For compiled procedures, this instruction sets up a new stack frame, -as described in @ref{Stack Layout}, and then dispatches to the first -instruction in the called procedure, relying on the called procedure -to return one value to the newly-created continuation. @end deffn @deffn Instruction goto/args nargs Like @code{call}, but reusing the current continuation. This -instruction implements tail calling as required by RnRS. +instruction implements tail calls as required by RnRS. For compiled procedures, that means that @code{goto/args} reuses the current frame instead of building a new one. The @code{goto/*} @@ -726,14 +751,14 @@ values. This is an optimization for the common @code{(apply values @deffn Instruction truncate-values nbinds nrest Used in multiple-value continuations, this instruction takes the -values that are on the stack (including the number-of-value marker) +values that are on the stack (including the number-of-values marker) and truncates them for a binding construct. For example, a call to @code{(receive (x y . z) (foo) ...)} would, logically speaking, pop off the values returned from @code{(foo)} and push them as three values, corresponding to @code{x}, @code{y}, and @code{z}. In that case, @var{nbinds} would be 3, and @var{nrest} would -be 1 (to indicate that one of the bindings was a rest arguments). +be 1 (to indicate that one of the bindings was a rest argument). Signals an error if there is an insufficient number of values. @end deffn @@ -760,6 +785,17 @@ Push the immediate value @code{1} onto the stack. Push @var{value}, a 16-bit integer, onto the stack. @end deffn +@deffn Instruction make-uint64 value +Push @var{value}, an unsigned 64-bit integer, onto the stack. The +value is encoded in 8 bytes, most significant byte first (big-endian). +@end deffn + +@deffn Instruction make-int64 value +Push @var{value}, a signed 64-bit integer, onto the stack. The value +is encoded in 8 bytes, most significant byte first (big-endian), in +twos-complement arithmetic. +@end deffn + @deffn Instruction make-false Push @code{#f} onto the stack. @end deffn @@ -776,15 +812,30 @@ Push @code{'()} onto the stack. Push @var{value}, an 8-bit character, onto the stack. @end deffn +@deffn Instruction make-char32 value +Push @var{value}, an 32-bit character, onto the stack. The value is +encoded in big-endian order. +@end deffn + +@deffn Instruction make-symbol +Pops a string off the stack, and pushes a symbol. +@end deffn + +@deffn Instruction make-keyword value +Pops a symbol off the stack, and pushes a keyword. +@end deffn + @deffn Instruction list n Pops off the top @var{n} values off of the stack, consing them up into a list, then pushes that list on the stack. What was the topmost value -will be the last element in the list. +will be the last element in the list. @var{n} is a two-byte value, +most significant byte first. @end deffn @deffn Instruction vector n Create and fill a vector with the top @var{n} values from the stack, -popping off those values and pushing on the resulting vector. +popping off those values and pushing on the resulting vector. @var{n} +is a two-byte value, like in @code{vector}. @end deffn @deffn Instruction mark @@ -817,7 +868,8 @@ pushes its elements on the stack. @subsubsection Miscellaneous Instructions @deffn Instruction nop -Does nothing! +Does nothing! Used for padding other instructions to certain +alignments. @end deffn @deffn Instruction halt @@ -850,9 +902,8 @@ Pushes ``the unspecified value'' onto the stack. @subsubsection Inlined Scheme Instructions The Scheme compiler can recognize the application of standard Scheme -procedures, or unbound variables that look like they are bound to -standard Scheme procedures. It tries to inline these small operations -to avoid the overhead of creating new stack frames. +procedures. It tries to inline these small operations to avoid the +overhead of creating new stack frames. Since most of these operations are historically implemented as C primitives, not inlining them would entail constantly calling out from @@ -876,14 +927,16 @@ stream. @deffnx Instruction eqv? x y @deffnx Instruction equal? x y @deffnx Instruction pair? x y -@deffnx Instruction list? x y +@deffnx Instruction list? x @deffnx Instruction set-car! pair x @deffnx Instruction set-cdr! pair x @deffnx Instruction slot-ref struct n @deffnx Instruction slot-set struct n x -@deffnx Instruction cons x +@deffnx Instruction cons x y @deffnx Instruction car x @deffnx Instruction cdr x +@deffnx Instruction vector-ref x y +@deffnx Instruction vector-set x n y Inlined implementations of their Scheme equivalents. @end deffn @@ -904,7 +957,9 @@ As in the previous section, the definitions below show stack parameters instead of instruction stream parameters. @deffn Instruction add x y +@deffnx Instruction add1 x @deffnx Instruction sub x y +@deffnx Instruction sub1 x @deffnx Instruction mul x y @deffnx Instruction div x y @deffnx Instruction quo x y @@ -917,3 +972,58 @@ parameters instead of instruction stream parameters. @deffnx Instruction ge? x y Inlined implementations of the corresponding mathematical operations. @end deffn + +@node Inlined Bytevector Instructions +@subsubsection Inlined Bytevector Instructions + +Bytevector operations correspond closely to what the current hardware +can do, so it makes sense to inline them to VM instructions, providing +a clear path for eventual native compilation. Without this, Scheme +programs would need other primitives for accessing raw bytes -- but +these primitives are as good as any. + +As in the previous section, the definitions below show stack +parameters instead of instruction stream parameters. + +The multibyte formats (@code{u16}, @code{f64}, etc) take an extra +endianness argument. Only aligned native accesses are currently +fast-pathed in Guile's VM. + +@deffn Instruction bv-u8-ref bv n +@deffnx Instruction bv-s8-ref bv n +@deffnx Instruction bv-u16-native-ref bv n +@deffnx Instruction bv-s16-native-ref bv n +@deffnx Instruction bv-u32-native-ref bv n +@deffnx Instruction bv-s32-native-ref bv n +@deffnx Instruction bv-u64-native-ref bv n +@deffnx Instruction bv-s64-native-ref bv n +@deffnx Instruction bv-f32-native-ref bv n +@deffnx Instruction bv-f64-native-ref bv n +@deffnx Instruction bv-u16-ref bv n endianness +@deffnx Instruction bv-s16-ref bv n endianness +@deffnx Instruction bv-u32-ref bv n endianness +@deffnx Instruction bv-s32-ref bv n endianness +@deffnx Instruction bv-u64-ref bv n endianness +@deffnx Instruction bv-s64-ref bv n endianness +@deffnx Instruction bv-f32-ref bv n endianness +@deffnx Instruction bv-f64-ref bv n endianness +@deffnx Instruction bv-u8-set bv n val +@deffnx Instruction bv-s8-set bv n val +@deffnx Instruction bv-u16-native-set bv n val +@deffnx Instruction bv-s16-native-set bv n val +@deffnx Instruction bv-u32-native-set bv n val +@deffnx Instruction bv-s32-native-set bv n val +@deffnx Instruction bv-u64-native-set bv n val +@deffnx Instruction bv-s64-native-set bv n val +@deffnx Instruction bv-f32-native-set bv n val +@deffnx Instruction bv-f64-native-set bv n val +@deffnx Instruction bv-u16-set bv n val endianness +@deffnx Instruction bv-s16-set bv n val endianness +@deffnx Instruction bv-u32-set bv n val endianness +@deffnx Instruction bv-s32-set bv n val endianness +@deffnx Instruction bv-u64-set bv n val endianness +@deffnx Instruction bv-s64-set bv n val endianness +@deffnx Instruction bv-f32-set bv n val endianness +@deffnx Instruction bv-f64-set bv n val endianness +Inlined implementations of the corresponding bytevector operations. +@end deffn diff --git a/doc/tutorial/Makefile.am b/doc/tutorial/Makefile.am index f49220da7..d359c4fed 100644 --- a/doc/tutorial/Makefile.am +++ b/doc/tutorial/Makefile.am @@ -4,20 +4,20 @@ ## ## This file is part of GUILE. ## -## GUILE 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, or +## GUILE is free software; you can redistribute it and/or modify it +## under the terms of the GNU Lesser General Public License as +## published by the Free Software Foundation; either version 3, or ## (at your option) any later version. -## +## ## GUILE 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 GUILE; see the file COPYING. If not, write -## to the Free Software Foundation, Inc., 51 Franklin Street, Fifth -## Floor, Boston, MA 02110-1301 USA +## GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with GUILE; see the file COPYING.LESSER. If not, +## write to the Free Software Foundation, Inc., 51 Franklin Street, +## Fifth Floor, Boston, MA 02110-1301 USA AUTOMAKE_OPTIONS = gnu diff --git a/emacs/Makefile.am b/emacs/Makefile.am index ad7a5c939..e18f30bf1 100644 --- a/emacs/Makefile.am +++ b/emacs/Makefile.am @@ -4,20 +4,20 @@ ## ## This file is part of GUILE. ## -## GUILE 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, or +## GUILE is free software; you can redistribute it and/or modify it +## under the terms of the GNU Lesser General Public License as +## published by the Free Software Foundation; either version 3, or ## (at your option) any later version. ## ## GUILE 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. +## GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU General Public -## License along with GUILE; see the file COPYING. If not, write -## to the Free Software Foundation, Inc., 51 Franklin Street, Fifth -## Floor, Boston, MA 02110-1301 USA +## You should have received a copy of the GNU Lesser General Public +## License along with GUILE; see the file COPYING.LESSER. If not, +## write to the Free Software Foundation, Inc., 51 Franklin Street, +## Fifth Floor, Boston, MA 02110-1301 USA AUTOMAKE_OPTIONS = gnu diff --git a/emacs/gds-scheme.el b/emacs/gds-scheme.el index b8a161b37..54c75a787 100755 --- a/emacs/gds-scheme.el +++ b/emacs/gds-scheme.el @@ -5,8 +5,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later -;;;; version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/emacs/gds-server.el b/emacs/gds-server.el index 86defc07b..d4fe997c2 100644 --- a/emacs/gds-server.el +++ b/emacs/gds-server.el @@ -5,8 +5,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later -;;;; version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/emacs/gds.el b/emacs/gds.el index 7a1486d8d..a9450d065 100644 --- a/emacs/gds.el +++ b/emacs/gds.el @@ -5,8 +5,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later -;;;; version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/emacs/gud-guile.el b/emacs/gud-guile.el index bd1b0ff26..5d295268f 100644 --- a/emacs/gud-guile.el +++ b/emacs/gud-guile.el @@ -2,20 +2,20 @@ ;; Copyright (C) 2001, 2006 Free Software Foundation, Inc. -;; GNU Emacs 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, or (at your option) -;; any later version. - -;; GNU Emacs 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 Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;; Boston, MA 02110-1301, USA. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free +;;;; Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +;;;; 02111-1307 USA ;;; Author: Thien-Thi Nguyen ;;; Version: 1 diff --git a/emacs/guile-c.el b/emacs/guile-c.el index b23ddd30f..1ccfd4dbc 100644 --- a/emacs/guile-c.el +++ b/emacs/guile-c.el @@ -2,20 +2,20 @@ ;; Copyright (C) 2001, 2006 Free Software Foundation, Inc. -;; 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 2, 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 COPYING. If not, write to the -;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;; Boston, MA 02110-1301, USA. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free +;;;; Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +;;;; 02111-1307 USA ;;; Commentary: diff --git a/emacs/guile-emacs.scm b/emacs/guile-emacs.scm index 000d0cc2e..4d99002b6 100644 --- a/emacs/guile-emacs.scm +++ b/emacs/guile-emacs.scm @@ -2,20 +2,20 @@ ;; Copyright (C) 2001 Keisuke Nishida -;; GNU Emacs 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, or (at your option) -;; any later version. - -;; GNU Emacs 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 Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;; Boston, MA 02110-1301, USA. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free +;;;; Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +;;;; 02111-1307 USA ;;; Code: diff --git a/emacs/guile-scheme.el b/emacs/guile-scheme.el index a6d8b1f19..5e112a0dc 100644 --- a/emacs/guile-scheme.el +++ b/emacs/guile-scheme.el @@ -2,20 +2,20 @@ ;; Copyright (C) 2001, 2006 Free Software Foundation, Inc. -;; GNU Emacs 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, or (at your option) -;; any later version. - -;; GNU Emacs 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 Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;; Boston, MA 02110-1301, USA. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free +;;;; Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +;;;; 02111-1307 USA ;;; Commentary: diff --git a/emacs/guile.el b/emacs/guile.el index e85c81c29..25a9b9b8e 100644 --- a/emacs/guile.el +++ b/emacs/guile.el @@ -2,20 +2,20 @@ ;; Copyright (C) 2001 Keisuke Nishida -;; GNU Emacs 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, or (at your option) -;; any later version. - -;; GNU Emacs 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 Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;; Boston, MA 02110-1301, USA. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free +;;;; Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +;;;; 02111-1307 USA ;;; Code: diff --git a/emacs/multistring.el b/emacs/multistring.el index ca17a8469..df8419542 100644 --- a/emacs/multistring.el +++ b/emacs/multistring.el @@ -2,22 +2,20 @@ ;; Copyright (C) 2000, 2006 Free Software Foundation, Inc. -;; This file is part of GNU Emacs. - -;; GNU Emacs 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, or (at your option) -;; any later version. - -;; GNU Emacs 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 Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;; Boston, MA 02110-1301, USA. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free +;;;; Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +;;;; 02111-1307 USA ;;; Author: Mikael Djurfeldt diff --git a/emacs/patch.el b/emacs/patch.el index 6bcb0876f..2fd20f579 100644 --- a/emacs/patch.el +++ b/emacs/patch.el @@ -2,20 +2,20 @@ ;; Copyright (C) 2001, 2006 Free Software Foundation, Inc. -;; GNU Emacs 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, or (at your option) -;; any later version. - -;; GNU Emacs 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 Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;; Boston, MA 02110-1301, USA. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free +;;;; Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +;;;; 02111-1307 USA ;;; Author: Thien-Thi Nguyen ;;; Version: 1 diff --git a/emacs/ppexpand.el b/emacs/ppexpand.el index 7ec3b1c45..f6c18765c 100644 --- a/emacs/ppexpand.el +++ b/emacs/ppexpand.el @@ -2,22 +2,20 @@ ;; Copyright (C) 2000, 2006 Free Software Foundation, Inc. -;; This file is part of GNU Emacs. - -;; GNU Emacs 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, or (at your option) -;; any later version. - -;; GNU Emacs 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 Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;; Boston, MA 02110-1301, USA. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free +;;;; Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +;;;; 02111-1307 USA ;;; Author: Mikael Djurfeldt diff --git a/emacs/update-changelog.el b/emacs/update-changelog.el index e0c0a4b11..c8dfa93a2 100644 --- a/emacs/update-changelog.el +++ b/emacs/update-changelog.el @@ -2,20 +2,20 @@ ;;; Copyright (C) 2001, 2006 Free Software Foundation, Inc. -;; 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 2, 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 COPYING. If not, write to the -;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;; Boston, MA 02110-1301, USA. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free +;;;; Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +;;;; 02111-1307 USA ;;; Commentary: diff --git a/examples/Makefile.am b/examples/Makefile.am index 84503088f..5de528a21 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -1,25 +1,95 @@ ## Process this file with Automake to create Makefile.in ## -## Copyright (C) 2001, 2006, 2008 Free Software Foundation, Inc. +## Copyright (C) 2001, 2006, 2008, 2009 Free Software Foundation, Inc. ## ## This file is part of GUILE. ## -## GUILE 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, or +## GUILE is free software; you can redistribute it and/or modify it +## under the terms of the GNU Lesser General Public License as +## published by the Free Software Foundation; either version 3, or ## (at your option) any later version. -## +## ## GUILE 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 GUILE; see the file COPYING. If not, write -## to the Free Software Foundation, Inc., 51 Franklin Street, Fifth -## Floor, Boston, MA 02110-1301 USA +## GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with GUILE; see the file COPYING.LESSER. If not, +## write to the Free Software Foundation, Inc., 51 Franklin Street, +## Fifth Floor, Boston, MA 02110-1301 USA -SUBDIRS = scripts box box-module box-dynamic box-dynamic-module\ - modules safe +EXTRA_DIST = README ChangeLog-2008 check.test \ + \ + scripts/README scripts/simple-hello.scm scripts/hello \ + scripts/fact \ + \ + box/README box/box.c \ + \ + box-module/README box-module/box.c \ + \ + box-dynamic/README box-dynamic/box.c \ + \ + box-dynamic-module/README box-dynamic-module/box.c \ + box-dynamic-module/box-module.scm box-dynamic-module/box-mixed.scm \ + \ + modules/README modules/module-0.scm modules/module-1.scm \ + modules/module-2.scm modules/main \ + \ + safe/README safe/safe safe/untrusted.scm safe/evil.scm -EXTRA_DIST = README ChangeLog-2008 +AM_CFLAGS = `PATH=$(bindir):$$PATH PKG_CONFIG_PATH=$(libdir)/pkgconfig $(bindir)/guile-config compile` +AM_LIBS = `PATH=$(bindir):$$PATH PKG_CONFIG_PATH=$(libdir)/pkgconfig $(bindir)/guile-config link` + + +box/box: box/box.o + -$(MKDIR_P) box + $(CC) $< $(AM_LIBS) -o $@ + +box/box.o: box/box.c + -$(MKDIR_P) box + $(CC) $(AM_CFLAGS) -c $< -o $@ + + +box-module/box: box-module/box.o + -$(MKDIR_P) box-module + $(CC) $< $(AM_LIBS) -o $@ + +box-module/box.o: box-module/box.c + -$(MKDIR_P) box-module + $(CC) $(AM_CFLAGS) -c $< -o $@ + + +libbox.la: box-dynamic/box.lo + $(top_builddir)/libtool --mode=link $(CC) $< $(AM_LIBS) -rpath $(libdir) -o $@ + +box-dynamic/box.lo: box-dynamic/box.c + -$(MKDIR_P) box-dynamic + $(top_builddir)/libtool --mode=compile $(CC) $(AM_CFLAGS) -c $< -o $@ + + +libbox-module.la: box-dynamic-module/box.lo + $(top_builddir)/libtool --mode=link $(CC) $< $(AM_LIBS) -rpath $(libdir) -o $@ + +box-dynamic-module/box.lo: box-dynamic-module/box.c + -$(MKDIR_P) box-dynamic-module + $(top_builddir)/libtool --mode=compile $(CC) $(AM_CFLAGS) -c $< -o $@ + + +installcheck: box/box box-module/box libbox.la libbox-module.la + LD_LIBRARY_PATH="$(libdir):$$LD_LIBRARY_PATH" \ + LTDL_LIBRARY_PATH="$(builddir):$$LTDL_LIBRARY_PATH" \ + GUILE_LOAD_PATH="$(abs_top_srcdir):$$GUILE_LOAD_PATH" \ + PATH="$(bindir):$$PATH" \ + GUILE_AUTO_COMPILE=0 \ + srcdir="$(srcdir)" \ + $(srcdir)/check.test + +CLEANFILES = \ + box/box box/box.o \ + box-module/box box-module/box.o + +clean-local: + $(top_builddir)/libtool --mode=clean rm -f \ + box-dynamic/box.lo libbox.la \ + box-dynamic-module/box.lo libbox-module.la diff --git a/examples/box-dynamic-module/Makefile.am b/examples/box-dynamic-module/Makefile.am deleted file mode 100644 index bf18f4f66..000000000 --- a/examples/box-dynamic-module/Makefile.am +++ /dev/null @@ -1,36 +0,0 @@ -## Process this file with Automake to create Makefile.in -## -## Copyright (C) 2001, 2006 Free Software Foundation, Inc. -## -## This file is part of GUILE. -## -## GUILE 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, or -## (at your option) any later version. -## -## GUILE 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 GUILE; see the file COPYING. If not, write -## to the Free Software Foundation, Inc., 51 Franklin Street, Fifth -## Floor, Boston, MA 02110-1301 USA - -EXTRA_DIST = README box.c box-module.scm box-mixed.scm check.test - -CFLAGS=`$(bindir)/guile-config compile` -LIBS=`$(bindir)/guile-config link` - -libbox-module: box.lo - sh ../../libtool --mode=link $(CC) $< $(LIBS) -rpath $(libdir) -o libbox-module.la - -box.lo: box.c - sh ../../libtool --mode=compile $(CC) $(CFLAGS) -c $< - -installcheck: libbox-module - LTDL_LIBRARY_PATH=.libs GUILE_LOAD_PATH=$(top_srcdir):$(srcdir) $(srcdir)/check.test - -CLEANFILES=libbox-module.la box.lo box.o diff --git a/examples/box-dynamic-module/box.c b/examples/box-dynamic-module/box.c index 7d6e2ce5d..e180565eb 100644 --- a/examples/box-dynamic-module/box.c +++ b/examples/box-dynamic-module/box.c @@ -2,20 +2,20 @@ * * Copyright (C) 1998,2001, 2006 Free Software Foundation, Inc. * - * 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 2, or (at your option) - * any later version. + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3, 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. + * 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 + * Lesser General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this software; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA + * You should have received a copy of the GNU Lesser General Public + * License along with this software; see the file COPYING.LESSER. If + * not, write to the Free Software Foundation, Inc., 51 Franklin + * Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* Include all needed declarations. */ diff --git a/examples/box-dynamic-module/check.test b/examples/box-dynamic-module/check.test deleted file mode 100755 index 935176d20..000000000 --- a/examples/box-dynamic-module/check.test +++ /dev/null @@ -1,48 +0,0 @@ -#!/bin/sh - -# must be run from this directory -guile=${GUILE-../../libguile/guile} - -set -e - -# -# ./box test #1 -# -$guile -c '(begin (use-modules (box-module)) (let ((b (make-box))) (display b) (newline)))' > TMP -cat < -EOF -rm -f TMP - -# -# ./box test #2 -# -$guile -c '(begin (use-modules (box-module)) (let ((b (make-box))) (display b) (newline) (box-set! b 1) (display b) (newline)))' > TMP -cat < -# -EOF -rm -f TMP - -# -# ./box test #3 -# -$guile -c '(begin (use-modules (box-module)) (let ((b (make-box))) (display b) (newline) (box-set! b 1) (display b) (newline) (display (box-ref b)) (newline)))' > TMP -cat < -# -1 -EOF -rm -f TMP - -# -# ./box test #4 -# -$guile -c '(begin (use-modules (box-mixed)) (let ((b (make-box-list 1 2 3))) (display b) (newline) (display (box-map 1+ b)) (newline)))' > TMP -cat < # #) -(# # #) -EOF -rm -f TMP - -# check.test ends here diff --git a/examples/box-dynamic/Makefile.am b/examples/box-dynamic/Makefile.am deleted file mode 100644 index 6fa20c59c..000000000 --- a/examples/box-dynamic/Makefile.am +++ /dev/null @@ -1,36 +0,0 @@ -## Process this file with Automake to create Makefile.in -## -## Copyright (C) 2001, 2006 Free Software Foundation, Inc. -## -## This file is part of GUILE. -## -## GUILE 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, or -## (at your option) any later version. -## -## GUILE 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 GUILE; see the file COPYING. If not, write -## to the Free Software Foundation, Inc., 51 Franklin Street, Fifth -## Floor, Boston, MA 02110-1301 USA - -EXTRA_DIST = README box.c check.test - -CFLAGS=`$(bindir)/guile-config compile` -LIBS=`$(bindir)/guile-config link` - -libbox: box.lo - sh ../../libtool --mode=link $(CC) $< $(LIBS) -rpath $(libdir) -o libbox.la - -box.lo: box.c - sh ../../libtool --mode=compile $(CC) $(CFLAGS) -c $< - -installcheck: libbox - LTDL_LIBRARY_PATH=.libs GUILE_LOAD_PATH=$(top_srcdir):$(srcdir) $(srcdir)/check.test - -CLEANFILES=libbox.la box.lo box.o diff --git a/examples/box-dynamic/box.c b/examples/box-dynamic/box.c index bb9529650..e96c011ab 100644 --- a/examples/box-dynamic/box.c +++ b/examples/box-dynamic/box.c @@ -2,20 +2,20 @@ * * Copyright (C) 1998,2001, 2006 Free Software Foundation, Inc. * - * 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 2, or (at your option) - * any later version. + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3, 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. + * 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 + * Lesser General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this software; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA + * You should have received a copy of the GNU Lesser General Public + * License along with this software; see the file COPYING.LESSER. If + * not, write to the Free Software Foundation, Inc., 51 Franklin + * Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* Include all needed declarations. */ diff --git a/examples/box-dynamic/check.test b/examples/box-dynamic/check.test deleted file mode 100755 index c0923365c..000000000 --- a/examples/box-dynamic/check.test +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/sh - -# must be run from this directory -guile=${GUILE-../../libguile/guile} - -set -e - -# -# ./box test #1 -# -$guile -c '(begin (load-extension "libbox" "scm_init_box") (let ((b (make-box))) (display b) (newline)))' > TMP -cat < -EOF -rm -f TMP - -# -# ./box test #2 -# -$guile -c '(begin (load-extension "libbox" "scm_init_box") (let ((b (make-box))) (display b) (newline) (box-set! b 1) (display b) (newline)))' > TMP -cat < -# -EOF -rm -f TMP - -# -# ./box test #3 -# -$guile -c '(begin (load-extension "libbox" "scm_init_box") (let ((b (make-box))) (display b) (newline) (box-set! b 1) (display b) (newline) (display (box-ref b)) (newline)))' > TMP -cat < -# -1 -EOF -rm -f TMP - -# check.test ends here diff --git a/examples/box-module/Makefile.am b/examples/box-module/Makefile.am deleted file mode 100644 index 4790a296c..000000000 --- a/examples/box-module/Makefile.am +++ /dev/null @@ -1,36 +0,0 @@ -## Process this file with Automake to create Makefile.in -## -## Copyright (C) 2001, 2006 Free Software Foundation, Inc. -## -## This file is part of GUILE. -## -## GUILE 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, or -## (at your option) any later version. -## -## GUILE 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 GUILE; see the file COPYING. If not, write -## to the Free Software Foundation, Inc., 51 Franklin Street, Fifth -## Floor, Boston, MA 02110-1301 USA - -EXTRA_DIST = README box.c check.test - -CFLAGS=`$(bindir)/guile-config compile` -LIBS=`$(bindir)/guile-config link` - -box: box.o - $(CC) $< $(LIBS) -o box - -box.o: box.c - $(CC) $(CFLAGS) -c $< - -installcheck: box - LD_LIBRARY_PATH=$(libdir) GUILE_LOAD_PATH=$(top_srcdir) $(srcdir)/check.test - -CLEANFILES=box box.o diff --git a/examples/box-module/box.c b/examples/box-module/box.c index b589b262f..b69377e38 100644 --- a/examples/box-module/box.c +++ b/examples/box-module/box.c @@ -2,20 +2,20 @@ * * Copyright (C) 1998,2001, 2006 Free Software Foundation, Inc. * - * 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 2, or (at your option) - * any later version. + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3, 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. + * 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 + * Lesser General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this software; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA + * You should have received a copy of the GNU Lesser General Public + * License along with this software; see the file COPYING.LESSER. If + * not, write to the Free Software Foundation, Inc., 51 Franklin + * Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* Include all needed declarations. */ diff --git a/examples/box-module/check.test b/examples/box-module/check.test deleted file mode 100755 index 28a79d45b..000000000 --- a/examples/box-module/check.test +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/sh - -# must be run from this directory -guile=${GUILE-../../libguile/guile} - -set -e - -# -# ./box test #1 -# -./box -c '(begin (use-modules (box-module)) (let ((b (make-box))) (display b) (newline)))' > TMP -cat < -EOF -rm -f TMP - -# -# ./box test #2 -# -./box -c '(begin (use-modules (box-module)) (let ((b (make-box))) (display b) (newline) (box-set! b 1) (display b) (newline)))' > TMP -cat < -# -EOF -rm -f TMP - -# -# ./box test #3 -# -./box -c '(begin (use-modules (box-module)) (let ((b (make-box))) (display b) (newline) (box-set! b 1) (display b) (newline) (display (box-ref b)) (newline)))' > TMP -cat < -# -1 -EOF -rm -f TMP - -# check.test ends here diff --git a/examples/box/Makefile.am b/examples/box/Makefile.am deleted file mode 100644 index 4790a296c..000000000 --- a/examples/box/Makefile.am +++ /dev/null @@ -1,36 +0,0 @@ -## Process this file with Automake to create Makefile.in -## -## Copyright (C) 2001, 2006 Free Software Foundation, Inc. -## -## This file is part of GUILE. -## -## GUILE 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, or -## (at your option) any later version. -## -## GUILE 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 GUILE; see the file COPYING. If not, write -## to the Free Software Foundation, Inc., 51 Franklin Street, Fifth -## Floor, Boston, MA 02110-1301 USA - -EXTRA_DIST = README box.c check.test - -CFLAGS=`$(bindir)/guile-config compile` -LIBS=`$(bindir)/guile-config link` - -box: box.o - $(CC) $< $(LIBS) -o box - -box.o: box.c - $(CC) $(CFLAGS) -c $< - -installcheck: box - LD_LIBRARY_PATH=$(libdir) GUILE_LOAD_PATH=$(top_srcdir) $(srcdir)/check.test - -CLEANFILES=box box.o diff --git a/examples/box/box.c b/examples/box/box.c index e36d650b3..0662c3d12 100644 --- a/examples/box/box.c +++ b/examples/box/box.c @@ -2,20 +2,20 @@ * * Copyright (C) 1998,2001, 2006 Free Software Foundation, Inc. * - * 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 2, or (at your option) - * any later version. + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3, 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. + * 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 + * Lesser General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this software; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA + * You should have received a copy of the GNU Lesser General Public + * License along with this software; see the file COPYING.LESSER. If + * not, write to the Free Software Foundation, Inc., 51 Franklin + * Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* Include all needed declarations. */ diff --git a/examples/box/check.test b/examples/box/check.test deleted file mode 100755 index 1909ffb7e..000000000 --- a/examples/box/check.test +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/sh - -# must be run from this directory -guile=${GUILE-../../libguile/guile} - -set -e - -# -# ./box test #1 -# -./box -c '(let ((b (make-box))) (display b) (newline))' > TMP -cat < -EOF -rm -f TMP - -# -# ./box test #2 -# -./box -c '(let ((b (make-box))) (display b) (newline) (box-set! b 1) (display b) (newline))' > TMP -cat < -# -EOF -rm -f TMP - -# -# ./box test #3 -# -./box -c '(let ((b (make-box))) (display b) (newline) (box-set! b 1) (display b) (newline) (display (box-ref b)) (newline))' > TMP -cat < -# -1 -EOF -rm -f TMP - -# check.test ends here diff --git a/examples/check.test b/examples/check.test new file mode 100755 index 000000000..b659ce8dc --- /dev/null +++ b/examples/check.test @@ -0,0 +1,238 @@ +#!/bin/sh + +# must be run from this directory +guile=${GUILE-../libguile/guile} +if [ -x $guile ] ; then + : +else + echo could not find guile interpreter. + echo '(are you running this script from' `dirname $0` '?)' + echo GUILE env var: ${GUILE-not set} + exit 1 +fi + +if test "X$srcdir" = X; then + srcdir=. +fi + +set -e + +# +# simple-hello.scm +# +$guile -s $srcdir/scripts/simple-hello.scm > TMP +cat < TMP +echo "Hello, World!" | diff -u - TMP +rm -f TMP + +$guile -s $srcdir/scripts/hello --version > TMP +echo "hello 0.0.1" | diff -u - TMP +rm -f TMP + +$guile -s $srcdir/scripts/hello --help > TMP +cat < TMP +cat < +EOF +rm -f TMP + +# +# ./box/box test #2 +# +./box/box -c '(let ((b (make-box))) (display b) (newline) (box-set! b 1) (display b) (newline))' > TMP +cat < +# +EOF +rm -f TMP + +# +# ./box/box test #3 +# +./box/box -c '(let ((b (make-box))) (display b) (newline) (box-set! b 1) (display b) (newline) (display (box-ref b)) (newline))' > TMP +cat < +# +1 +EOF +rm -f TMP + + + +# +# ./box-module/box test #1 +# +./box-module/box -c '(begin (use-modules (box-module)) (let ((b (make-box))) (display b) (newline)))' > TMP +cat < +EOF +rm -f TMP + +# +# ./box-module/box test #2 +# +./box-module/box -c '(begin (use-modules (box-module)) (let ((b (make-box))) (display b) (newline) (box-set! b 1) (display b) (newline)))' > TMP +cat < +# +EOF +rm -f TMP + +# +# ./box-module/box test #3 +# +./box-module/box -c '(begin (use-modules (box-module)) (let ((b (make-box))) (display b) (newline) (box-set! b 1) (display b) (newline) (display (box-ref b)) (newline)))' > TMP +cat < +# +1 +EOF +rm -f TMP + + +# +# ./box-dynamic/box test #1 +# +$guile -c '(begin (load-extension "libbox" "scm_init_box") (let ((b (make-box))) (display b) (newline)))' > TMP +cat < +EOF +rm -f TMP + +# +# ./box-dynamic/box test #2 +# +$guile -c '(begin (load-extension "libbox" "scm_init_box") (let ((b (make-box))) (display b) (newline) (box-set! b 1) (display b) (newline)))' > TMP +cat < +# +EOF +rm -f TMP + +# +# ./box-dynamic/box test #3 +# +$guile -c '(begin (load-extension "libbox" "scm_init_box") (let ((b (make-box))) (display b) (newline) (box-set! b 1) (display b) (newline) (display (box-ref b)) (newline)))' > TMP +cat < +# +1 +EOF +rm -f TMP + + +# +# ./box-dynamic-module/box test #1 +# +$guile -L $srcdir/box-dynamic-module \ + -c '(begin (use-modules (box-module)) (let ((b (make-box))) (display b) (newline)))' > TMP +cat < +EOF +rm -f TMP + +# +# ./box-dynamic-module/box test #2 +# +$guile -L $srcdir/box-dynamic-module \ + -c '(begin (use-modules (box-module)) (let ((b (make-box))) (display b) (newline) (box-set! b 1) (display b) (newline)))' > TMP +cat < +# +EOF +rm -f TMP + +# +# ./box-dynamic-module/box test #3 +# +$guile -L $srcdir/box-dynamic-module \ + -c '(begin (use-modules (box-module)) (let ((b (make-box))) (display b) (newline) (box-set! b 1) (display b) (newline) (display (box-ref b)) (newline)))' > TMP +cat < +# +1 +EOF +rm -f TMP + +# +# ./box-dynamic-module/box test #4 +# +$guile -L $srcdir/box-dynamic-module \ + -c '(begin (use-modules (box-mixed)) (let ((b (make-box-list 1 2 3))) (display b) (newline) (display (box-map 1+ b)) (newline)))' > TMP +cat < # #) +(# # #) +EOF +rm -f TMP + + + +# +# ./main test +# +$guile -L $srcdir/modules -s $srcdir/modules/main > TMP +cat < TMP +cat < TMP +cat < TMP -cat < TMP -cat < TMP -cat < TMP -cat < TMP -echo "Hello, World!" | diff -u - TMP -rm -f TMP - -$guile -s $srcdir/hello --version > TMP -echo "hello 0.0.1" | diff -u - TMP -rm -f TMP - -$guile -s $srcdir/hello --help > TMP -cat <.~%")) (ref-env (assoc-ref args 'reference-environment)) (bdwgc-env (or (assoc-ref args 'bdwgc-environment) (string-append "GUILE=" bench-dir - "/../pre-inst-guile"))) + "/../meta/guile"))) (prof-opts (assoc-ref args 'profile-options))) (for-each (lambda (benchmark) (let ((ref (parse-result (run-reference-guile ref-env diff --git a/gdb-pre-inst-guile.in b/gdb-pre-inst-guile.in deleted file mode 100644 index d1f4e38ec..000000000 --- a/gdb-pre-inst-guile.in +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/sh - -# Copyright (C) 2002, 2006, 2008 Free Software Foundation -# -# This file is part of GUILE. -# -# GUILE 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, or -# (at your option) any later version. -# -# GUILE 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 GUILE; see the file COPYING. If not, write -# to the Free Software Foundation, Inc., 51 Franklin Street, Fifth -# Floor, Boston, MA 02110-1301 USA - -# Commentary: - -# Usage: gdb-pre-inst-guile [ARGS] -# -# This script runs Guile from the build tree under GDB. See -# ./pre-inst-guile for more information. -# -# In addition to running ./gdb-pre-inst-guile, sometimes it's useful to -# run e.g. ./check-guile -i ./gdb-pre-inst-guile foo.test. - -# Code: - -set -e -# env (set by configure) -top_builddir="@top_builddir_absolute@" -exec ${top_builddir}/pre-inst-guile-env libtool --mode=execute \ - gdb --args ${top_builddir}/libguile/guile "$@" diff --git a/gdbinit b/gdbinit index 381cf8477..b66e3e249 100644 --- a/gdbinit +++ b/gdbinit @@ -148,11 +148,6 @@ define nextframe output $vmdl newline set $vmsp=$vmsp-1 - sputs "el:\t" - output $vmsp - sputs "\t" - gwrite *$vmsp - set $vmsp=$vmsp-1 set $vmnlocs=(int)$vmbp->nlocs while $vmnlocs > 0 sputs "loc #" diff --git a/guile-config/Makefile.am b/guile-config/Makefile.am deleted file mode 100644 index cedcba968..000000000 --- a/guile-config/Makefile.am +++ /dev/null @@ -1,46 +0,0 @@ -## Process this file with Automake to create Makefile.in -## Jim Blandy --- September 1997 -## -## Copyright (C) 1998, 1999, 2001, 2006, 2007, 2008 Free Software Foundation, Inc. -## -## This file is part of GUILE. -## -## GUILE 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, or -## (at your option) any later version. -## -## GUILE 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 GUILE; see the file COPYING. If not, write -## to the Free Software Foundation, Inc., 51 Franklin Street, Fifth -## Floor, Boston, MA 02110-1301 USA - -bin_SCRIPTS=guile-config -CLEANFILES=guile-config -EXTRA_DIST=guile-config.in guile.m4 ChangeLog-2008 - -## FIXME: in the future there will be direct automake support for -## doing this. When that happens, switch over. -aclocaldir = $(datadir)/aclocal -aclocal_DATA = guile.m4 - -## We use @-...-@ as the substitution brackets here, instead of the -## usual @...@, so autoconf doesn't go and substitute the values -## directly into the left-hand sides of the sed substitutions. *sigh* -guile-config: guile-config.in ${top_builddir}/libguile/libpath.h - rm -f guile-config.tmp - sed < ${srcdir}/guile-config.in > guile-config.tmp \ - -e 's|@-bindir-@|${bindir}|' \ - -e s:@-GUILE_VERSION-@:${GUILE_VERSION}: - chmod +x guile-config.tmp - mv guile-config.tmp guile-config - -## Get rid of any copies of the configuration script under the old -## name, so people don't end up running ancient copies of it. -install-exec-local: - rm -f ${bindir}/build-guile diff --git a/guile-readline/Makefile.am b/guile-readline/Makefile.am index 94e6f9741..9df82bcb1 100644 --- a/guile-readline/Makefile.am +++ b/guile-readline/Makefile.am @@ -2,20 +2,20 @@ ## ## Copyright (C) 1998, 1999, 2000, 2001, 2004, 2006, 2007, 2008 Free Software Foundation, Inc. ## -## This file is part of GUILE. +## This file is part of guile-readline. ## -## GUILE 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, or +## guile-readline 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. ## -## GUILE 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. +## guile-readline 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 GUILE; see the file COPYING. If not, write +## You should have received a copy of the GNU General Public License +## along with guile-readline; see the file COPYING. If not, write ## to the Free Software Foundation, Inc., 51 Franklin Street, Fifth ## Floor, Boston, MA 02110-1301 USA diff --git a/guile-readline/configure.in b/guile-readline/configure.ac similarity index 56% rename from guile-readline/configure.in rename to guile-readline/configure.ac index 9098a31e6..f24fc9418 100644 --- a/guile-readline/configure.in +++ b/guile-readline/configure.ac @@ -7,7 +7,7 @@ AC_INIT(guile-readline, ]), [bug-guile@gnu.org]) -AC_CONFIG_AUX_DIR([.]) +AC_CONFIG_AUX_DIR([../build-aux]) AC_CONFIG_SRCDIR(readline.c) AM_CONFIG_HEADER([guile-readline-config.h]) AM_INIT_AUTOMAKE([foreign no-define]) @@ -38,6 +38,7 @@ for termlib in ncurses curses termcap terminfo termlib ; do [LIBS="-l${termlib} $LIBS"; break]) done +AC_LIB_LINKFLAGS(readline) AC_CHECK_LIB(readline, readline) if test $ac_cv_lib_readline_readline = no; then AC_MSG_WARN([libreadline was not found on your system.]) @@ -53,77 +54,6 @@ dnl install paren matching on the Guile command line (when using dnl readline for input), so it's completely optional. AC_CHECK_FUNCS(rl_get_keymap) -dnl Check for rl_pre_input_hook. This is more complicated because on -dnl some systems (HP/UX), the linker wont let us treat -dnl rl_pre_input_hook as a function when it really is a function -dnl pointer. - -AC_MSG_CHECKING([for rl_pre_input_hook]) -AC_CACHE_VAL(ac_cv_var_rl_pre_input_hook, -[AC_TRY_LINK([ -#include -#include -], [ -rl_pre_input_hook = 0; -], -ac_cv_var_rl_pre_input_hook=yes, -ac_cv_var_rl_pre_input_hook=no)]) -AC_MSG_RESULT($ac_cv_var_rl_pre_input_hook) -if test $ac_cv_var_rl_pre_input_hook = yes; then - AC_DEFINE(HAVE_RL_PRE_INPUT_HOOK,1, - [Define if rl_pre_input_hook is available.]) -fi - - -AC_MSG_CHECKING(if readline clears SA_RESTART flag for SIGWINCH) -AC_CACHE_VAL(guile_cv_sigwinch_sa_restart_cleared, -AC_TRY_RUN([#include -#include -#include - -int -hook () -{ - struct sigaction action; - - sigaction (SIGWINCH, NULL, &action); - rl_cleanup_after_signal(); - - /* exit with 0 if readline disabled SA_RESTART */ - exit (action.sa_flags & SA_RESTART); -} - -int -main () -{ - struct sigaction action; - - sigaction (SIGWINCH, NULL, &action); - action.sa_flags |= SA_RESTART; - sigaction (SIGWINCH, &action, NULL); - - /* Give readline something to read. Otherwise, it might hang, for - example when run as a background process with job control. - */ - rl_instream = fopen ("/dev/null", "r"); - if (rl_instream == NULL) - { - perror ("/dev/null"); - exit (1); - } - - rl_pre_input_hook = hook; - readline (""); -}], -guile_cv_sigwinch_sa_restart_cleared=yes, -guile_cv_sigwinch_sa_restart_cleared=no, -guile_cv_sigwinch_sa_restart_cleared=yes)) -AC_MSG_RESULT($guile_cv_sigwinch_sa_restart_cleared) -if test $guile_cv_sigwinch_sa_restart_cleared = yes; then - AC_DEFINE(GUILE_SIGWINCH_SA_RESTART_CLEARED, 1, - [Define if readline disables SA_RESTART.]) -fi - AC_CACHE_CHECK([for rl_getc_function pointer in readline], ac_cv_var_rl_getc_function, [AC_TRY_LINK([ diff --git a/guile-readline/ice-9/Makefile.am b/guile-readline/ice-9/Makefile.am index d1e7c8270..ffa767e99 100644 --- a/guile-readline/ice-9/Makefile.am +++ b/guile-readline/ice-9/Makefile.am @@ -2,20 +2,20 @@ ## ## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006, 2008 Free Software Foundation, Inc. ## -## This file is part of GUILE. +## This file is part of guile-readline. ## -## GUILE 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, or +## guile-readline 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. ## -## GUILE 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. +## guile-readline 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 GUILE; see the file COPYING. If not, write +## You should have received a copy of the GNU General Public License +## along with guile-readline; see the file COPYING. If not, write ## to the Free Software Foundation, Inc., 51 Franklin Street, Fifth ## Floor, Boston, MA 02110-1301 USA diff --git a/guile-readline/ice-9/readline.scm b/guile-readline/ice-9/readline.scm index c35602f0c..96af69e2f 100644 --- a/guile-readline/ice-9/readline.scm +++ b/guile-readline/ice-9/readline.scm @@ -4,7 +4,7 @@ ;;;; ;;;; 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 2, or (at your option) +;;;; the Free Software Foundation; either version 3, or (at your option) ;;;; any later version. ;;;; ;;;; This program is distributed in the hope that it will be useful, @@ -169,24 +169,22 @@ (define-public (set-readline-read-hook! h) (set! read-hook h)) -(if (provided? 'regex) - (begin - (define-public apropos-completion-function - (let ((completions '())) - (lambda (text cont?) - (if (not cont?) - (set! completions - (map symbol->string - (apropos-internal - (string-append "^" (regexp-quote text)))))) - (if (null? completions) - #f - (let ((retval (car completions))) - (begin (set! completions (cdr completions)) - retval)))))) +(define-public apropos-completion-function + (let ((completions '())) + (lambda (text cont?) + (if (not cont?) + (set! completions + (map symbol->string + (apropos-internal + (string-append "^" (regexp-quote text)))))) + (if (null? completions) + #f + (let ((retval (car completions))) + (begin (set! completions (cdr completions)) + retval)))))) - (set! *readline-completion-function* apropos-completion-function) - )) +(if (provided? 'regex) + (set! *readline-completion-function* apropos-completion-function)) (define-public (with-readline-completion-function completer thunk) "With @var{completer} as readline completion function, call @var{thunk}." diff --git a/guile-readline/readline.c b/guile-readline/readline.c index 58599cacc..7f86ceb3d 100644 --- a/guile-readline/readline.c +++ b/guile-readline/readline.c @@ -4,7 +4,7 @@ * * 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 2, or (at your option) + * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, @@ -530,26 +530,6 @@ match_paren (int x, int k) } #endif /* HAVE_RL_GET_KEYMAP */ -#if defined (HAVE_RL_PRE_INPUT_HOOK) && defined (GUILE_SIGWINCH_SA_RESTART_CLEARED) -/* Readline disables SA_RESTART on SIGWINCH. - * This code turns it back on. - */ -static int -sigwinch_enable_restart (void) -{ -#ifdef HAVE_SIGINTERRUPT - siginterrupt (SIGWINCH, 0); -#else - struct sigaction action; - - sigaction (SIGWINCH, NULL, &action); - action.sa_flags |= SA_RESTART; - sigaction (SIGWINCH, &action, NULL); -#endif - return 0; -} -#endif - #endif /* HAVE_RL_GETC_FUNCTION */ void @@ -569,9 +549,6 @@ scm_init_readline () #endif rl_basic_word_break_characters = "\t\n\"'`;()"; rl_readline_name = "Guile"; -#if defined (HAVE_RL_PRE_INPUT_HOOK) && defined (GUILE_SIGWINCH_SA_RESTART_CLEARED) - rl_pre_input_hook = sigwinch_enable_restart; -#endif reentry_barrier_mutex = scm_permanent_object (scm_make_mutex ()); scm_init_opts (scm_readline_options, diff --git a/guile-readline/readline.h b/guile-readline/readline.h index 6242c5642..2bf5f8000 100644 --- a/guile-readline/readline.h +++ b/guile-readline/readline.h @@ -5,7 +5,7 @@ * * 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 2, or (at your option) + * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, diff --git a/guile-tools.in b/guile-tools.in deleted file mode 100644 index ca940a0da..000000000 --- a/guile-tools.in +++ /dev/null @@ -1,118 +0,0 @@ -#!/bin/sh - -# Copyright (C) 2001, 2003, 2006, 2008 Free Software Foundation, Inc. -# -# 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 2, 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 software; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -# Boston, MA 02110-1301 USA - -# Usage: See `help' func below. -# -# TODO -# - handle pre-install invocation -# - "full" option processing (but see comment below) -# -# Author: Thien-Thi Nguyen - -help () -{ - cat <symbol (string-append "imports:" (number->string counter))))))) -(define-macro (use-elisp-file file-name . imports) - "Load Elisp code file @var{file-name} and import its definitions +(define use-elisp-file + (procedure->memoizing-macro + (lambda (exp env) + "Load Elisp code file @var{file-name} and import its definitions into the current Scheme module. If any @var{imports} are specified, they are interpreted as selection and renaming specifiers as per @code{use-modules}." - (let ((export-module-name (export-module-name))) - `(begin - (fluid-set! ,elisp-export-module (resolve-module ',export-module-name)) - (beautify-user-module! (resolve-module ',export-module-name)) - (load-elisp-file ,file-name) - (use-modules (,export-module-name ,@imports)) - (fluid-set! ,elisp-export-module #f)))) + (let ((file-name (cadr exp)) + (env (cddr exp))) + (let ((export-module-name (export-module-name))) + `(begin + (fluid-set! ,elisp-export-module (resolve-module ',export-module-name)) + (beautify-user-module! (resolve-module ',export-module-name)) + (load-elisp-file ,file-name) + (use-modules (,export-module-name ,@imports)) + (fluid-set! ,elisp-export-module #f))))))) -(define-macro (use-elisp-library library . imports) - "Load Elisp library @var{library} and import its definitions into +(define use-elisp-library + (procedure->memoizing-macro + (lambda (exp env) + "Load Elisp library @var{library} and import its definitions into the current Scheme module. If any @var{imports} are specified, they are interpreted as selection and renaming specifiers as per @code{use-modules}." - (let ((export-module-name (export-module-name))) - `(begin - (fluid-set! ,elisp-export-module (resolve-module ',export-module-name)) - (beautify-user-module! (resolve-module ',export-module-name)) - (load-elisp-library ,library) - (use-modules (,export-module-name ,@imports)) - (fluid-set! ,elisp-export-module #f)))) + (let ((library (cadr exp)) + (env (cddr exp))) + (let ((export-module-name (export-module-name))) + `(begin + (fluid-set! ,elisp-export-module (resolve-module ',export-module-name)) + (beautify-user-module! (resolve-module ',export-module-name)) + (load-elisp-library ,library) + (use-modules (,export-module-name ,@imports)) + (fluid-set! ,elisp-export-module #f))))))) (define (export-to-elisp . defs) "Export procedures and variables specified by @var{defs} to Elisp. diff --git a/lang/elisp/internals/lambda.scm b/lang/elisp/internals/lambda.scm index 9917c08bd..f7c7a4d01 100644 --- a/lang/elisp/internals/lambda.scm +++ b/lang/elisp/internals/lambda.scm @@ -1,4 +1,5 @@ (define-module (lang elisp internals lambda) + #:use-syntax (lang elisp expand) #:use-module (lang elisp internals fset) #:use-module (lang elisp transform) #:export (parse-formals diff --git a/lang/elisp/primitives/fns.scm b/lang/elisp/primitives/fns.scm index f7a4aa003..7beb8a51c 100644 --- a/lang/elisp/primitives/fns.scm +++ b/lang/elisp/primitives/fns.scm @@ -26,7 +26,8 @@ (fset 'symbol-function fref/error-if-void) -(fset 'macroexpand macroexpand) +;; FIXME -- lost in the syncase conversion +;; (fset 'macroexpand macroexpand) (fset 'subrp (lambda (obj) diff --git a/lang/elisp/primitives/syntax.scm b/lang/elisp/primitives/syntax.scm index 6babb3dd3..118b3bc0c 100644 --- a/lang/elisp/primitives/syntax.scm +++ b/lang/elisp/primitives/syntax.scm @@ -1,4 +1,5 @@ (define-module (lang elisp primitives syntax) + #:use-syntax (lang elisp expand) #:use-module (lang elisp internals evaluation) #:use-module (lang elisp internals fset) #:use-module (lang elisp internals lambda) diff --git a/lang/elisp/transform.scm b/lang/elisp/transform.scm index ee288a722..09159c073 100644 --- a/lang/elisp/transform.scm +++ b/lang/elisp/transform.scm @@ -1,4 +1,5 @@ (define-module (lang elisp transform) + #:use-syntax (lang elisp expand) #:use-module (lang elisp internals trace) #:use-module (lang elisp internals fset) #:use-module (lang elisp internals evaluation) @@ -26,23 +27,27 @@ (define (syntax-error x) (error "Syntax error in expression" x)) -(define-macro (scheme exp . module) - (let ((m (if (null? module) - the-root-module - (save-module-excursion - (lambda () - ;; In order for `resolve-module' to work as - ;; expected, the current module must contain the - ;; `app' variable. This is not true for #:pure - ;; modules, specifically (lang elisp base). So, - ;; switch to the root module (guile) before calling - ;; resolve-module. - (set-current-module the-root-module) - (resolve-module (car module))))))) - (let ((x `(,eval (,quote ,exp) ,m))) - ;;(write x) - ;;(newline) - x))) +(define scheme + (procedure->memoizing-macro + (lambda (exp env) + (let ((exp (cadr exp)) + (module (cddr exp))) + (let ((m (if (null? module) + the-root-module + (save-module-excursion + (lambda () + ;; In order for `resolve-module' to work as + ;; expected, the current module must contain the + ;; `app' variable. This is not true for #:pure + ;; modules, specifically (lang elisp base). So, + ;; switch to the root module (guile) before calling + ;; resolve-module. + (set-current-module the-root-module) + (resolve-module (car module))))))) + (let ((x `(,eval (,quote ,exp) ,m))) + ;;(write x) + ;;(newline) + x)))))) (define (transformer x) (cond ((pair? x) diff --git a/lib/Makefile.am b/lib/Makefile.am index bd59069f8..075cd75b7 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -9,9 +9,9 @@ # the same distribution terms as the rest of that program. # # Generated by gnulib-tool. -# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --lgpl --libtool --macro-prefix=gl --no-vc-files alloca-opt autobuild extensions full-read full-write strcase strftime +# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --lgpl --libtool --macro-prefix=gl --no-vc-files alloca-opt autobuild byteswap canonicalize-lgpl environ extensions flock fpieee full-read full-write havelib iconv_open-utf lib-symbol-versions lib-symbol-visibility libunistring putenv stdlib strcase strftime striconveh string verify vsnprintf -AUTOMAKE_OPTIONS = 1.5 gnits +AUTOMAKE_OPTIONS = 1.5 gnits subdir-objects SUBDIRS = noinst_HEADERS = @@ -27,6 +27,7 @@ DISTCLEANFILES = MAINTAINERCLEANFILES = AM_CPPFLAGS = +AM_CFLAGS = noinst_LTLIBRARIES += libgnu.la @@ -53,6 +54,51 @@ EXTRA_DIST += alloca.in.h ## end gnulib module alloca-opt +## begin gnulib module byteswap + +BUILT_SOURCES += $(BYTESWAP_H) + +# We need the following in order to create when the system +# doesn't have one. +byteswap.h: byteswap.in.h + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + cat $(srcdir)/byteswap.in.h; \ + } > $@-t + mv -f $@-t $@ +MOSTLYCLEANFILES += byteswap.h byteswap.h-t + +EXTRA_DIST += byteswap.in.h + +## end gnulib module byteswap + +## begin gnulib module c-ctype + +libgnu_la_SOURCES += c-ctype.h c-ctype.c + +## end gnulib module c-ctype + +## begin gnulib module c-strcase + +libgnu_la_SOURCES += c-strcase.h c-strcasecmp.c c-strncasecmp.c + +## end gnulib module c-strcase + +## begin gnulib module c-strcaseeq + + +EXTRA_DIST += c-strcaseeq.h + +## end gnulib module c-strcaseeq + +## begin gnulib module canonicalize-lgpl + + +EXTRA_DIST += canonicalize-lgpl.c canonicalize.h + +EXTRA_libgnu_la_SOURCES += canonicalize-lgpl.c + +## end gnulib module canonicalize-lgpl + ## begin gnulib module configmake # Retrieve values of the variables through 'configure' followed by @@ -73,7 +119,7 @@ EXTRA_DIST += alloca.in.h # The Automake-defined pkg* macros are appended, in the order # listed in the Automake 1.10a+ documentation. configmake.h: Makefile - rm -f $@-t $@ + rm -f $@-t { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ echo '#define PREFIX "$(prefix)"'; \ echo '#define EXEC_PREFIX "$(exec_prefix)"'; \ @@ -103,12 +149,74 @@ configmake.h: Makefile echo '#define PKGLIBDIR "$(pkglibdir)"'; \ echo '#define PKGLIBEXECDIR "$(pkglibexecdir)"'; \ } | sed '/""/d' > $@-t - mv $@-t $@ + if test -f $@ && cmp $@-t $@ > /dev/null; then \ + rm -f $@-t; \ + else \ + rm -f $@; mv $@-t $@; \ + fi + BUILT_SOURCES += configmake.h CLEANFILES += configmake.h configmake.h-t ## end gnulib module configmake +## begin gnulib module errno + +BUILT_SOURCES += $(ERRNO_H) + +# We need the following in order to create when the system +# doesn't have one that is POSIX compliant. +errno.h: errno.in.h + rm -f $@-t $@ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ + sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ + -e 's|@''NEXT_ERRNO_H''@|$(NEXT_ERRNO_H)|g' \ + -e 's|@''EMULTIHOP_HIDDEN''@|$(EMULTIHOP_HIDDEN)|g' \ + -e 's|@''EMULTIHOP_VALUE''@|$(EMULTIHOP_VALUE)|g' \ + -e 's|@''ENOLINK_HIDDEN''@|$(ENOLINK_HIDDEN)|g' \ + -e 's|@''ENOLINK_VALUE''@|$(ENOLINK_VALUE)|g' \ + -e 's|@''EOVERFLOW_HIDDEN''@|$(EOVERFLOW_HIDDEN)|g' \ + -e 's|@''EOVERFLOW_VALUE''@|$(EOVERFLOW_VALUE)|g' \ + < $(srcdir)/errno.in.h; \ + } > $@-t + mv $@-t $@ +MOSTLYCLEANFILES += errno.h errno.h-t + +EXTRA_DIST += errno.in.h + +## end gnulib module errno + +## begin gnulib module float + +BUILT_SOURCES += $(FLOAT_H) + +# We need the following in order to create when the system +# doesn't have one that works with the given compiler. +float.h: float.in.h + rm -f $@-t $@ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ + sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ + -e 's|@''NEXT_FLOAT_H''@|$(NEXT_FLOAT_H)|g' \ + < $(srcdir)/float.in.h; \ + } > $@-t + mv $@-t $@ +MOSTLYCLEANFILES += float.h float.h-t + +EXTRA_DIST += float.in.h + +## end gnulib module float + +## begin gnulib module flock + + +EXTRA_DIST += flock.c + +EXTRA_libgnu_la_SOURCES += flock.c + +## end gnulib module flock + ## begin gnulib module full-read libgnu_la_SOURCES += full-read.h full-read.c @@ -121,6 +229,91 @@ libgnu_la_SOURCES += full-write.h full-write.c ## end gnulib module full-write +## begin gnulib module getpagesize + + +EXTRA_DIST += getpagesize.c + +EXTRA_libgnu_la_SOURCES += getpagesize.c + +## end gnulib module getpagesize + +## begin gnulib module gperf + +GPERF = gperf + +## end gnulib module gperf + +## begin gnulib module havelib + + +EXTRA_DIST += $(top_srcdir)/build-aux/config.rpath + +## end gnulib module havelib + +## begin gnulib module iconv_open + +BUILT_SOURCES += $(ICONV_H) + +# We need the following in order to create when the system +# doesn't have one that works with the given compiler. +iconv.h: iconv.in.h + rm -f $@-t $@ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ + sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ + -e 's|@''NEXT_ICONV_H''@|$(NEXT_ICONV_H)|g' \ + -e 's|@''ICONV_CONST''@|$(ICONV_CONST)|g' \ + -e 's|@''REPLACE_ICONV''@|$(REPLACE_ICONV)|g' \ + -e 's|@''REPLACE_ICONV_OPEN''@|$(REPLACE_ICONV_OPEN)|g' \ + -e 's|@''REPLACE_ICONV_UTF''@|$(REPLACE_ICONV_UTF)|g' \ + < $(srcdir)/iconv.in.h; \ + } > $@-t + mv $@-t $@ +MOSTLYCLEANFILES += iconv.h iconv.h-t + +iconv_open-aix.h: iconv_open-aix.gperf + $(GPERF) -m 10 $(srcdir)/iconv_open-aix.gperf > $(srcdir)/iconv_open-aix.h-t + mv $(srcdir)/iconv_open-aix.h-t $(srcdir)/iconv_open-aix.h +iconv_open-hpux.h: iconv_open-hpux.gperf + $(GPERF) -m 10 $(srcdir)/iconv_open-hpux.gperf > $(srcdir)/iconv_open-hpux.h-t + mv $(srcdir)/iconv_open-hpux.h-t $(srcdir)/iconv_open-hpux.h +iconv_open-irix.h: iconv_open-irix.gperf + $(GPERF) -m 10 $(srcdir)/iconv_open-irix.gperf > $(srcdir)/iconv_open-irix.h-t + mv $(srcdir)/iconv_open-irix.h-t $(srcdir)/iconv_open-irix.h +iconv_open-osf.h: iconv_open-osf.gperf + $(GPERF) -m 10 $(srcdir)/iconv_open-osf.gperf > $(srcdir)/iconv_open-osf.h-t + mv $(srcdir)/iconv_open-osf.h-t $(srcdir)/iconv_open-osf.h +BUILT_SOURCES += iconv_open-aix.h iconv_open-hpux.h iconv_open-irix.h iconv_open-osf.h +MOSTLYCLEANFILES += iconv_open-aix.h-t iconv_open-hpux.h-t iconv_open-irix.h-t iconv_open-osf.h-t +MAINTAINERCLEANFILES += iconv_open-aix.h iconv_open-hpux.h iconv_open-irix.h iconv_open-osf.h +EXTRA_DIST += iconv_open-aix.h iconv_open-hpux.h iconv_open-irix.h iconv_open-osf.h + +EXTRA_DIST += iconv.in.h iconv_open-aix.gperf iconv_open-hpux.gperf iconv_open-irix.gperf iconv_open-osf.gperf iconv_open.c + +EXTRA_libgnu_la_SOURCES += iconv_open.c + +## end gnulib module iconv_open + +## begin gnulib module iconv_open-utf + + +EXTRA_DIST += iconv.c iconv_close.c + +EXTRA_libgnu_la_SOURCES += iconv.c iconv_close.c + +## end gnulib module iconv_open-utf + +## begin gnulib module lib-symbol-visibility + +# The value of $(CFLAG_VISIBILITY) needs to be added to the CFLAGS for the +# compilation of all sources that make up the library. This line here does it +# only for the gnulib part of it. The developer is responsible for adding +# $(CFLAG_VISIBILITY) to the Makefile.ams of the other portions of the library. +AM_CFLAGS += $(CFLAG_VISIBILITY) + +## end gnulib module lib-symbol-visibility + ## begin gnulib module link-warning LINK_WARNING_H=$(top_srcdir)/build-aux/link-warning.h @@ -144,21 +337,37 @@ all-local: charset.alias ref-add.sed ref-del.sed charset_alias = $(DESTDIR)$(libdir)/charset.alias charset_tmp = $(DESTDIR)$(libdir)/charset.tmp -install-exec-local: all-local - test $(GLIBC21) != no || $(mkinstalldirs) $(DESTDIR)$(libdir) +install-exec-local: install-exec-localcharset +install-exec-localcharset: all-local + if test $(GLIBC21) = no; then \ + case '$(host_os)' in \ + darwin[56]*) \ + need_charset_alias=true ;; \ + darwin* | cygwin* | mingw* | pw32* | cegcc*) \ + need_charset_alias=false ;; \ + *) \ + need_charset_alias=true ;; \ + esac ; \ + else \ + need_charset_alias=false ; \ + fi ; \ + if $$need_charset_alias; then \ + $(mkinstalldirs) $(DESTDIR)$(libdir) ; \ + fi ; \ if test -f $(charset_alias); then \ sed -f ref-add.sed $(charset_alias) > $(charset_tmp) ; \ $(INSTALL_DATA) $(charset_tmp) $(charset_alias) ; \ rm -f $(charset_tmp) ; \ else \ - if test $(GLIBC21) = no; then \ + if $$need_charset_alias; then \ sed -f ref-add.sed charset.alias > $(charset_tmp) ; \ $(INSTALL_DATA) $(charset_tmp) $(charset_alias) ; \ rm -f $(charset_tmp) ; \ fi ; \ fi -uninstall-local: all-local +uninstall-local: uninstall-localcharset +uninstall-localcharset: all-local if test -f $(charset_alias); then \ sed -f ref-del.sed $(charset_alias) > $(charset_tmp); \ if grep '^# Packages using this file: $$' $(charset_tmp) \ @@ -187,6 +396,23 @@ EXTRA_DIST += config.charset ref-add.sin ref-del.sin ## end gnulib module localcharset +## begin gnulib module malloc-posix + + +EXTRA_DIST += malloc.c + +EXTRA_libgnu_la_SOURCES += malloc.c + +## end gnulib module malloc-posix + +## begin gnulib module malloca + +libgnu_la_SOURCES += malloca.c + +EXTRA_DIST += malloca.h malloca.valgrind + +## end gnulib module malloca + ## begin gnulib module mbrlen @@ -214,6 +440,40 @@ EXTRA_libgnu_la_SOURCES += mbsinit.c ## end gnulib module mbsinit +## begin gnulib module memchr + + +EXTRA_DIST += memchr.c memchr.valgrind + +EXTRA_libgnu_la_SOURCES += memchr.c + +## end gnulib module memchr + +## begin gnulib module pathmax + + +EXTRA_DIST += pathmax.h + +## end gnulib module pathmax + +## begin gnulib module putenv + + +EXTRA_DIST += putenv.c + +EXTRA_libgnu_la_SOURCES += putenv.c + +## end gnulib module putenv + +## begin gnulib module readlink + + +EXTRA_DIST += readlink.c + +EXTRA_libgnu_la_SOURCES += readlink.c + +## end gnulib module readlink + ## begin gnulib module safe-read @@ -232,6 +492,12 @@ EXTRA_libgnu_la_SOURCES += safe-write.c ## end gnulib module safe-write +## begin gnulib module size_max + +libgnu_la_SOURCES += size_max.h + +## end gnulib module size_max + ## begin gnulib module stdbool BUILT_SOURCES += $(STDBOOL_H) @@ -250,6 +516,200 @@ EXTRA_DIST += stdbool.in.h ## end gnulib module stdbool +## begin gnulib module stdint + +BUILT_SOURCES += $(STDINT_H) + +# We need the following in order to create when the system +# doesn't have one that works with the given compiler. +stdint.h: stdint.in.h + rm -f $@-t $@ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + sed -e 's/@''HAVE_STDINT_H''@/$(HAVE_STDINT_H)/g' \ + -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ + -e 's|@''NEXT_STDINT_H''@|$(NEXT_STDINT_H)|g' \ + -e 's/@''HAVE_SYS_TYPES_H''@/$(HAVE_SYS_TYPES_H)/g' \ + -e 's/@''HAVE_INTTYPES_H''@/$(HAVE_INTTYPES_H)/g' \ + -e 's/@''HAVE_SYS_INTTYPES_H''@/$(HAVE_SYS_INTTYPES_H)/g' \ + -e 's/@''HAVE_SYS_BITYPES_H''@/$(HAVE_SYS_BITYPES_H)/g' \ + -e 's/@''HAVE_LONG_LONG_INT''@/$(HAVE_LONG_LONG_INT)/g' \ + -e 's/@''HAVE_UNSIGNED_LONG_LONG_INT''@/$(HAVE_UNSIGNED_LONG_LONG_INT)/g' \ + -e 's/@''APPLE_UNIVERSAL_BUILD''@/$(APPLE_UNIVERSAL_BUILD)/g' \ + -e 's/@''BITSIZEOF_PTRDIFF_T''@/$(BITSIZEOF_PTRDIFF_T)/g' \ + -e 's/@''PTRDIFF_T_SUFFIX''@/$(PTRDIFF_T_SUFFIX)/g' \ + -e 's/@''BITSIZEOF_SIG_ATOMIC_T''@/$(BITSIZEOF_SIG_ATOMIC_T)/g' \ + -e 's/@''HAVE_SIGNED_SIG_ATOMIC_T''@/$(HAVE_SIGNED_SIG_ATOMIC_T)/g' \ + -e 's/@''SIG_ATOMIC_T_SUFFIX''@/$(SIG_ATOMIC_T_SUFFIX)/g' \ + -e 's/@''BITSIZEOF_SIZE_T''@/$(BITSIZEOF_SIZE_T)/g' \ + -e 's/@''SIZE_T_SUFFIX''@/$(SIZE_T_SUFFIX)/g' \ + -e 's/@''BITSIZEOF_WCHAR_T''@/$(BITSIZEOF_WCHAR_T)/g' \ + -e 's/@''HAVE_SIGNED_WCHAR_T''@/$(HAVE_SIGNED_WCHAR_T)/g' \ + -e 's/@''WCHAR_T_SUFFIX''@/$(WCHAR_T_SUFFIX)/g' \ + -e 's/@''BITSIZEOF_WINT_T''@/$(BITSIZEOF_WINT_T)/g' \ + -e 's/@''HAVE_SIGNED_WINT_T''@/$(HAVE_SIGNED_WINT_T)/g' \ + -e 's/@''WINT_T_SUFFIX''@/$(WINT_T_SUFFIX)/g' \ + < $(srcdir)/stdint.in.h; \ + } > $@-t + mv $@-t $@ +MOSTLYCLEANFILES += stdint.h stdint.h-t + +EXTRA_DIST += stdint.in.h + +## end gnulib module stdint + +## begin gnulib module stdio + +BUILT_SOURCES += stdio.h + +# We need the following in order to create when the system +# doesn't have one that works with the given compiler. +stdio.h: stdio.in.h + rm -f $@-t $@ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ + sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ + -e 's|@''NEXT_STDIO_H''@|$(NEXT_STDIO_H)|g' \ + -e 's|@''GNULIB_FPRINTF''@|$(GNULIB_FPRINTF)|g' \ + -e 's|@''GNULIB_FPRINTF_POSIX''@|$(GNULIB_FPRINTF_POSIX)|g' \ + -e 's|@''GNULIB_PRINTF''@|$(GNULIB_PRINTF)|g' \ + -e 's|@''GNULIB_PRINTF_POSIX''@|$(GNULIB_PRINTF_POSIX)|g' \ + -e 's|@''GNULIB_SNPRINTF''@|$(GNULIB_SNPRINTF)|g' \ + -e 's|@''GNULIB_SPRINTF_POSIX''@|$(GNULIB_SPRINTF_POSIX)|g' \ + -e 's|@''GNULIB_VFPRINTF''@|$(GNULIB_VFPRINTF)|g' \ + -e 's|@''GNULIB_VFPRINTF_POSIX''@|$(GNULIB_VFPRINTF_POSIX)|g' \ + -e 's|@''GNULIB_VPRINTF''@|$(GNULIB_VPRINTF)|g' \ + -e 's|@''GNULIB_VPRINTF_POSIX''@|$(GNULIB_VPRINTF_POSIX)|g' \ + -e 's|@''GNULIB_VSNPRINTF''@|$(GNULIB_VSNPRINTF)|g' \ + -e 's|@''GNULIB_VSPRINTF_POSIX''@|$(GNULIB_VSPRINTF_POSIX)|g' \ + -e 's|@''GNULIB_DPRINTF''@|$(GNULIB_DPRINTF)|g' \ + -e 's|@''GNULIB_VDPRINTF''@|$(GNULIB_VDPRINTF)|g' \ + -e 's|@''GNULIB_VASPRINTF''@|$(GNULIB_VASPRINTF)|g' \ + -e 's|@''GNULIB_OBSTACK_PRINTF''@|$(GNULIB_OBSTACK_PRINTF)|g' \ + -e 's|@''GNULIB_OBSTACK_PRINTF_POSIX''@|$(GNULIB_OBSTACK_PRINTF_POSIX)|g' \ + -e 's|@''GNULIB_FOPEN''@|$(GNULIB_FOPEN)|g' \ + -e 's|@''GNULIB_FREOPEN''@|$(GNULIB_FREOPEN)|g' \ + -e 's|@''GNULIB_FSEEK''@|$(GNULIB_FSEEK)|g' \ + -e 's|@''GNULIB_FSEEKO''@|$(GNULIB_FSEEKO)|g' \ + -e 's|@''GNULIB_FTELL''@|$(GNULIB_FTELL)|g' \ + -e 's|@''GNULIB_FTELLO''@|$(GNULIB_FTELLO)|g' \ + -e 's|@''GNULIB_FFLUSH''@|$(GNULIB_FFLUSH)|g' \ + -e 's|@''GNULIB_FPURGE''@|$(GNULIB_FPURGE)|g' \ + -e 's|@''GNULIB_FCLOSE''@|$(GNULIB_FCLOSE)|g' \ + -e 's|@''GNULIB_FPUTC''@|$(GNULIB_FPUTC)|g' \ + -e 's|@''GNULIB_PUTC''@|$(GNULIB_PUTC)|g' \ + -e 's|@''GNULIB_PUTCHAR''@|$(GNULIB_PUTCHAR)|g' \ + -e 's|@''GNULIB_FPUTS''@|$(GNULIB_FPUTS)|g' \ + -e 's|@''GNULIB_PUTS''@|$(GNULIB_PUTS)|g' \ + -e 's|@''GNULIB_FWRITE''@|$(GNULIB_FWRITE)|g' \ + -e 's|@''GNULIB_GETDELIM''@|$(GNULIB_GETDELIM)|g' \ + -e 's|@''GNULIB_GETLINE''@|$(GNULIB_GETLINE)|g' \ + -e 's|@''GNULIB_PERROR''@|$(GNULIB_PERROR)|g' \ + -e 's|@''GNULIB_STDIO_H_SIGPIPE''@|$(GNULIB_STDIO_H_SIGPIPE)|g' \ + -e 's|@''REPLACE_STDIO_WRITE_FUNCS''@|$(REPLACE_STDIO_WRITE_FUNCS)|g' \ + -e 's|@''REPLACE_FPRINTF''@|$(REPLACE_FPRINTF)|g' \ + -e 's|@''REPLACE_VFPRINTF''@|$(REPLACE_VFPRINTF)|g' \ + -e 's|@''REPLACE_PRINTF''@|$(REPLACE_PRINTF)|g' \ + -e 's|@''REPLACE_VPRINTF''@|$(REPLACE_VPRINTF)|g' \ + -e 's|@''REPLACE_SNPRINTF''@|$(REPLACE_SNPRINTF)|g' \ + -e 's|@''HAVE_DECL_SNPRINTF''@|$(HAVE_DECL_SNPRINTF)|g' \ + -e 's|@''REPLACE_VSNPRINTF''@|$(REPLACE_VSNPRINTF)|g' \ + -e 's|@''HAVE_DECL_VSNPRINTF''@|$(HAVE_DECL_VSNPRINTF)|g' \ + -e 's|@''REPLACE_SPRINTF''@|$(REPLACE_SPRINTF)|g' \ + -e 's|@''REPLACE_VSPRINTF''@|$(REPLACE_VSPRINTF)|g' \ + -e 's|@''HAVE_DPRINTF''@|$(HAVE_DPRINTF)|g' \ + -e 's|@''REPLACE_DPRINTF''@|$(REPLACE_DPRINTF)|g' \ + -e 's|@''HAVE_VDPRINTF''@|$(HAVE_VDPRINTF)|g' \ + -e 's|@''REPLACE_VDPRINTF''@|$(REPLACE_VDPRINTF)|g' \ + -e 's|@''HAVE_VASPRINTF''@|$(HAVE_VASPRINTF)|g' \ + -e 's|@''REPLACE_VASPRINTF''@|$(REPLACE_VASPRINTF)|g' \ + -e 's|@''HAVE_DECL_OBSTACK_PRINTF''@|$(HAVE_DECL_OBSTACK_PRINTF)|g' \ + -e 's|@''REPLACE_OBSTACK_PRINTF''@|$(REPLACE_OBSTACK_PRINTF)|g' \ + -e 's|@''REPLACE_FOPEN''@|$(REPLACE_FOPEN)|g' \ + -e 's|@''REPLACE_FREOPEN''@|$(REPLACE_FREOPEN)|g' \ + -e 's|@''REPLACE_FSEEKO''@|$(REPLACE_FSEEKO)|g' \ + -e 's|@''REPLACE_FSEEK''@|$(REPLACE_FSEEK)|g' \ + -e 's|@''REPLACE_FTELLO''@|$(REPLACE_FTELLO)|g' \ + -e 's|@''REPLACE_FTELL''@|$(REPLACE_FTELL)|g' \ + -e 's|@''REPLACE_FFLUSH''@|$(REPLACE_FFLUSH)|g' \ + -e 's|@''REPLACE_FPURGE''@|$(REPLACE_FPURGE)|g' \ + -e 's|@''HAVE_DECL_FPURGE''@|$(HAVE_DECL_FPURGE)|g' \ + -e 's|@''REPLACE_FCLOSE''@|$(REPLACE_FCLOSE)|g' \ + -e 's|@''HAVE_DECL_GETDELIM''@|$(HAVE_DECL_GETDELIM)|g' \ + -e 's|@''HAVE_DECL_GETLINE''@|$(HAVE_DECL_GETLINE)|g' \ + -e 's|@''REPLACE_GETLINE''@|$(REPLACE_GETLINE)|g' \ + -e 's|@''REPLACE_PERROR''@|$(REPLACE_PERROR)|g' \ + -e '/definition of GL_LINK_WARNING/r $(LINK_WARNING_H)' \ + < $(srcdir)/stdio.in.h; \ + } > $@-t + mv $@-t $@ +MOSTLYCLEANFILES += stdio.h stdio.h-t + +EXTRA_DIST += stdio-write.c stdio.in.h + +EXTRA_libgnu_la_SOURCES += stdio-write.c + +## end gnulib module stdio + +## begin gnulib module stdlib + +BUILT_SOURCES += stdlib.h + +# We need the following in order to create when the system +# doesn't have one that works with the given compiler. +stdlib.h: stdlib.in.h + rm -f $@-t $@ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ + sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ + -e 's|@''NEXT_STDLIB_H''@|$(NEXT_STDLIB_H)|g' \ + -e 's|@''HAVE_RANDOM_H''@|$(HAVE_RANDOM_H)|g' \ + -e 's|@''GNULIB_MALLOC_POSIX''@|$(GNULIB_MALLOC_POSIX)|g' \ + -e 's|@''GNULIB_REALLOC_POSIX''@|$(GNULIB_REALLOC_POSIX)|g' \ + -e 's|@''GNULIB_CALLOC_POSIX''@|$(GNULIB_CALLOC_POSIX)|g' \ + -e 's|@''GNULIB_ATOLL''@|$(GNULIB_ATOLL)|g' \ + -e 's|@''GNULIB_GETLOADAVG''@|$(GNULIB_GETLOADAVG)|g' \ + -e 's|@''GNULIB_GETSUBOPT''@|$(GNULIB_GETSUBOPT)|g' \ + -e 's|@''GNULIB_MKDTEMP''@|$(GNULIB_MKDTEMP)|g' \ + -e 's|@''GNULIB_MKSTEMP''@|$(GNULIB_MKSTEMP)|g' \ + -e 's|@''GNULIB_PUTENV''@|$(GNULIB_PUTENV)|g' \ + -e 's|@''GNULIB_RANDOM_R''@|$(GNULIB_RANDOM_R)|g' \ + -e 's|@''GNULIB_RPMATCH''@|$(GNULIB_RPMATCH)|g' \ + -e 's|@''GNULIB_SETENV''@|$(GNULIB_SETENV)|g' \ + -e 's|@''GNULIB_STRTOD''@|$(GNULIB_STRTOD)|g' \ + -e 's|@''GNULIB_STRTOLL''@|$(GNULIB_STRTOLL)|g' \ + -e 's|@''GNULIB_STRTOULL''@|$(GNULIB_STRTOULL)|g' \ + -e 's|@''GNULIB_UNSETENV''@|$(GNULIB_UNSETENV)|g' \ + -e 's|@''HAVE_ATOLL''@|$(HAVE_ATOLL)|g' \ + -e 's|@''HAVE_CALLOC_POSIX''@|$(HAVE_CALLOC_POSIX)|g' \ + -e 's|@''HAVE_GETSUBOPT''@|$(HAVE_GETSUBOPT)|g' \ + -e 's|@''HAVE_MALLOC_POSIX''@|$(HAVE_MALLOC_POSIX)|g' \ + -e 's|@''HAVE_MKDTEMP''@|$(HAVE_MKDTEMP)|g' \ + -e 's|@''HAVE_REALLOC_POSIX''@|$(HAVE_REALLOC_POSIX)|g' \ + -e 's|@''HAVE_RANDOM_R''@|$(HAVE_RANDOM_R)|g' \ + -e 's|@''HAVE_RPMATCH''@|$(HAVE_RPMATCH)|g' \ + -e 's|@''HAVE_SETENV''@|$(HAVE_SETENV)|g' \ + -e 's|@''HAVE_STRTOD''@|$(HAVE_STRTOD)|g' \ + -e 's|@''HAVE_STRTOLL''@|$(HAVE_STRTOLL)|g' \ + -e 's|@''HAVE_STRTOULL''@|$(HAVE_STRTOULL)|g' \ + -e 's|@''HAVE_STRUCT_RANDOM_DATA''@|$(HAVE_STRUCT_RANDOM_DATA)|g' \ + -e 's|@''HAVE_SYS_LOADAVG_H''@|$(HAVE_SYS_LOADAVG_H)|g' \ + -e 's|@''HAVE_UNSETENV''@|$(HAVE_UNSETENV)|g' \ + -e 's|@''HAVE_DECL_GETLOADAVG''@|$(HAVE_DECL_GETLOADAVG)|g' \ + -e 's|@''REPLACE_MKSTEMP''@|$(REPLACE_MKSTEMP)|g' \ + -e 's|@''REPLACE_PUTENV''@|$(REPLACE_PUTENV)|g' \ + -e 's|@''REPLACE_STRTOD''@|$(REPLACE_STRTOD)|g' \ + -e 's|@''VOID_UNSETENV''@|$(VOID_UNSETENV)|g' \ + -e '/definition of GL_LINK_WARNING/r $(LINK_WARNING_H)' \ + < $(srcdir)/stdlib.in.h; \ + } > $@-t + mv $@-t $@ +MOSTLYCLEANFILES += stdlib.h stdlib.h-t + +EXTRA_DIST += stdlib.in.h + +## end gnulib module stdlib + ## begin gnulib module strcase @@ -275,6 +735,97 @@ EXTRA_libgnu_la_SOURCES += strftime.c ## end gnulib module strftime +## begin gnulib module striconveh + +libgnu_la_SOURCES += striconveh.h striconveh.c +if GL_COND_LIBTOOL +libgnu_la_LDFLAGS += $(LTLIBICONV) +endif + +EXTRA_DIST += iconveh.h + +## end gnulib module striconveh + +## begin gnulib module string + +BUILT_SOURCES += string.h + +# We need the following in order to create when the system +# doesn't have one that works with the given compiler. +string.h: string.in.h + rm -f $@-t $@ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ + sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ + -e 's|@''NEXT_STRING_H''@|$(NEXT_STRING_H)|g' \ + -e 's|@''GNULIB_MBSLEN''@|$(GNULIB_MBSLEN)|g' \ + -e 's|@''GNULIB_MBSNLEN''@|$(GNULIB_MBSNLEN)|g' \ + -e 's|@''GNULIB_MBSCHR''@|$(GNULIB_MBSCHR)|g' \ + -e 's|@''GNULIB_MBSRCHR''@|$(GNULIB_MBSRCHR)|g' \ + -e 's|@''GNULIB_MBSSTR''@|$(GNULIB_MBSSTR)|g' \ + -e 's|@''GNULIB_MBSCASECMP''@|$(GNULIB_MBSCASECMP)|g' \ + -e 's|@''GNULIB_MBSNCASECMP''@|$(GNULIB_MBSNCASECMP)|g' \ + -e 's|@''GNULIB_MBSPCASECMP''@|$(GNULIB_MBSPCASECMP)|g' \ + -e 's|@''GNULIB_MBSCASESTR''@|$(GNULIB_MBSCASESTR)|g' \ + -e 's|@''GNULIB_MBSCSPN''@|$(GNULIB_MBSCSPN)|g' \ + -e 's|@''GNULIB_MBSPBRK''@|$(GNULIB_MBSPBRK)|g' \ + -e 's|@''GNULIB_MBSSPN''@|$(GNULIB_MBSSPN)|g' \ + -e 's|@''GNULIB_MBSSEP''@|$(GNULIB_MBSSEP)|g' \ + -e 's|@''GNULIB_MBSTOK_R''@|$(GNULIB_MBSTOK_R)|g' \ + -e 's|@''GNULIB_MEMCHR''@|$(GNULIB_MEMCHR)|g' \ + -e 's|@''GNULIB_MEMMEM''@|$(GNULIB_MEMMEM)|g' \ + -e 's|@''GNULIB_MEMPCPY''@|$(GNULIB_MEMPCPY)|g' \ + -e 's|@''GNULIB_MEMRCHR''@|$(GNULIB_MEMRCHR)|g' \ + -e 's|@''GNULIB_RAWMEMCHR''@|$(GNULIB_RAWMEMCHR)|g' \ + -e 's|@''GNULIB_STPCPY''@|$(GNULIB_STPCPY)|g' \ + -e 's|@''GNULIB_STPNCPY''@|$(GNULIB_STPNCPY)|g' \ + -e 's|@''GNULIB_STRCHRNUL''@|$(GNULIB_STRCHRNUL)|g' \ + -e 's|@''GNULIB_STRDUP''@|$(GNULIB_STRDUP)|g' \ + -e 's|@''GNULIB_STRNDUP''@|$(GNULIB_STRNDUP)|g' \ + -e 's|@''GNULIB_STRNLEN''@|$(GNULIB_STRNLEN)|g' \ + -e 's|@''GNULIB_STRPBRK''@|$(GNULIB_STRPBRK)|g' \ + -e 's|@''GNULIB_STRSEP''@|$(GNULIB_STRSEP)|g' \ + -e 's|@''GNULIB_STRSTR''@|$(GNULIB_STRSTR)|g' \ + -e 's|@''GNULIB_STRCASESTR''@|$(GNULIB_STRCASESTR)|g' \ + -e 's|@''GNULIB_STRTOK_R''@|$(GNULIB_STRTOK_R)|g' \ + -e 's|@''GNULIB_STRERROR''@|$(GNULIB_STRERROR)|g' \ + -e 's|@''GNULIB_STRSIGNAL''@|$(GNULIB_STRSIGNAL)|g' \ + -e 's|@''GNULIB_STRVERSCMP''@|$(GNULIB_STRVERSCMP)|g' \ + -e 's|@''HAVE_DECL_MEMMEM''@|$(HAVE_DECL_MEMMEM)|g' \ + -e 's|@''HAVE_MEMPCPY''@|$(HAVE_MEMPCPY)|g' \ + -e 's|@''HAVE_DECL_MEMRCHR''@|$(HAVE_DECL_MEMRCHR)|g' \ + -e 's|@''HAVE_RAWMEMCHR''@|$(HAVE_RAWMEMCHR)|g' \ + -e 's|@''HAVE_STPCPY''@|$(HAVE_STPCPY)|g' \ + -e 's|@''HAVE_STPNCPY''@|$(HAVE_STPNCPY)|g' \ + -e 's|@''HAVE_STRCHRNUL''@|$(HAVE_STRCHRNUL)|g' \ + -e 's|@''HAVE_DECL_STRDUP''@|$(HAVE_DECL_STRDUP)|g' \ + -e 's|@''HAVE_STRNDUP''@|$(HAVE_STRNDUP)|g' \ + -e 's|@''HAVE_DECL_STRNDUP''@|$(HAVE_DECL_STRNDUP)|g' \ + -e 's|@''HAVE_DECL_STRNLEN''@|$(HAVE_DECL_STRNLEN)|g' \ + -e 's|@''HAVE_STRPBRK''@|$(HAVE_STRPBRK)|g' \ + -e 's|@''HAVE_STRSEP''@|$(HAVE_STRSEP)|g' \ + -e 's|@''HAVE_STRCASESTR''@|$(HAVE_STRCASESTR)|g' \ + -e 's|@''HAVE_DECL_STRTOK_R''@|$(HAVE_DECL_STRTOK_R)|g' \ + -e 's|@''HAVE_DECL_STRERROR''@|$(HAVE_DECL_STRERROR)|g' \ + -e 's|@''HAVE_DECL_STRSIGNAL''@|$(HAVE_DECL_STRSIGNAL)|g' \ + -e 's|@''HAVE_STRVERSCMP''@|$(HAVE_STRVERSCMP)|g' \ + -e 's|@''REPLACE_MEMCHR''@|$(REPLACE_MEMCHR)|g' \ + -e 's|@''REPLACE_MEMMEM''@|$(REPLACE_MEMMEM)|g' \ + -e 's|@''REPLACE_STRCASESTR''@|$(REPLACE_STRCASESTR)|g' \ + -e 's|@''REPLACE_STRDUP''@|$(REPLACE_STRDUP)|g' \ + -e 's|@''REPLACE_STRSTR''@|$(REPLACE_STRSTR)|g' \ + -e 's|@''REPLACE_STRERROR''@|$(REPLACE_STRERROR)|g' \ + -e 's|@''REPLACE_STRSIGNAL''@|$(REPLACE_STRSIGNAL)|g' \ + -e '/definition of GL_LINK_WARNING/r $(LINK_WARNING_H)' \ + < $(srcdir)/string.in.h; \ + } > $@-t + mv $@-t $@ +MOSTLYCLEANFILES += string.h string.h-t + +EXTRA_DIST += string.in.h + +## end gnulib module string + ## begin gnulib module strings BUILT_SOURCES += strings.h @@ -299,6 +850,32 @@ EXTRA_DIST += strings.in.h ## end gnulib module strings +## begin gnulib module sys_file + +BUILT_SOURCES += $(SYS_FILE_H) + +# We need the following in order to create when the system +# has one that is incomplete. +sys/file.h: sys_file.in.h + @MKDIR_P@ sys + rm -f $@-t $@ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + sed -e 's/@''HAVE_SYS_FILE_H''@/$(HAVE_SYS_FILE_H)/g' \ + -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ + -e 's|@''NEXT_SYS_FILE_H''@|$(NEXT_SYS_FILE_H)|g' \ + -e 's/@''HAVE_FLOCK''@/$(HAVE_FLOCK)/g' \ + -e 's/@''GNULIB_FLOCK''@/$(GNULIB_FLOCK)/g' \ + < $(srcdir)/sys_file.in.h; \ + } > $@-t + mv $@-t $@ +MOSTLYCLEANFILES += sys/file.h sys/file.h-t +MOSTLYCLEANDIRS += sys + +EXTRA_DIST += sys_file.in.h + +## end gnulib module sys_file + ## begin gnulib module time BUILT_SOURCES += time.h @@ -312,6 +889,7 @@ time.h: time.in.h -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ -e 's|@NEXT_TIME_H''@|$(NEXT_TIME_H)|g' \ -e 's|@REPLACE_LOCALTIME_R''@|$(REPLACE_LOCALTIME_R)|g' \ + -e 's|@REPLACE_MKTIME''@|$(REPLACE_MKTIME)|g' \ -e 's|@REPLACE_NANOSLEEP''@|$(REPLACE_NANOSLEEP)|g' \ -e 's|@REPLACE_STRPTIME''@|$(REPLACE_STRPTIME)|g' \ -e 's|@REPLACE_TIMEGM''@|$(REPLACE_TIMEGM)|g' \ @@ -364,6 +942,7 @@ unistd.h: unistd.in.h -e 's|@''GNULIB_GETPAGESIZE''@|$(GNULIB_GETPAGESIZE)|g' \ -e 's|@''GNULIB_GETUSERSHELL''@|$(GNULIB_GETUSERSHELL)|g' \ -e 's|@''GNULIB_LCHOWN''@|$(GNULIB_LCHOWN)|g' \ + -e 's|@''GNULIB_LINK''@|$(GNULIB_LINK)|g' \ -e 's|@''GNULIB_LSEEK''@|$(GNULIB_LSEEK)|g' \ -e 's|@''GNULIB_READLINK''@|$(GNULIB_READLINK)|g' \ -e 's|@''GNULIB_SLEEP''@|$(GNULIB_SLEEP)|g' \ @@ -378,6 +957,7 @@ unistd.h: unistd.in.h -e 's|@''HAVE_GETHOSTNAME''@|$(HAVE_GETHOSTNAME)|g' \ -e 's|@''HAVE_GETPAGESIZE''@|$(HAVE_GETPAGESIZE)|g' \ -e 's|@''HAVE_GETUSERSHELL''@|$(HAVE_GETUSERSHELL)|g' \ + -e 's|@''HAVE_LINK''@|$(HAVE_LINK)|g' \ -e 's|@''HAVE_READLINK''@|$(HAVE_READLINK)|g' \ -e 's|@''HAVE_SLEEP''@|$(HAVE_SLEEP)|g' \ -e 's|@''HAVE_DECL_ENVIRON''@|$(HAVE_DECL_ENVIRON)|g' \ @@ -386,6 +966,7 @@ unistd.h: unistd.in.h -e 's|@''HAVE_SYS_PARAM_H''@|$(HAVE_SYS_PARAM_H)|g' \ -e 's|@''REPLACE_CHOWN''@|$(REPLACE_CHOWN)|g' \ -e 's|@''REPLACE_CLOSE''@|$(REPLACE_CLOSE)|g' \ + -e 's|@''REPLACE_DUP2''@|$(REPLACE_DUP2)|g' \ -e 's|@''REPLACE_FCHDIR''@|$(REPLACE_FCHDIR)|g' \ -e 's|@''REPLACE_GETCWD''@|$(REPLACE_GETCWD)|g' \ -e 's|@''REPLACE_GETPAGESIZE''@|$(REPLACE_GETPAGESIZE)|g' \ @@ -403,12 +984,74 @@ EXTRA_DIST += unistd.in.h ## end gnulib module unistd +## begin gnulib module unistr/base + + +EXTRA_DIST += unistr.h + +## end gnulib module unistr/base + +## begin gnulib module unistr/u8-mbtouc + +libgnu_la_SOURCES += unistr/u8-mbtouc.c unistr/u8-mbtouc-aux.c + +## end gnulib module unistr/u8-mbtouc + +## begin gnulib module unistr/u8-mbtouc-unsafe + +libgnu_la_SOURCES += unistr/u8-mbtouc-unsafe.c unistr/u8-mbtouc-unsafe-aux.c + +## end gnulib module unistr/u8-mbtouc-unsafe + +## begin gnulib module unistr/u8-mbtoucr + +libgnu_la_SOURCES += unistr/u8-mbtoucr.c + +## end gnulib module unistr/u8-mbtoucr + +## begin gnulib module unistr/u8-prev + +libgnu_la_SOURCES += unistr/u8-prev.c + +## end gnulib module unistr/u8-prev + +## begin gnulib module unistr/u8-uctomb + +libgnu_la_SOURCES += unistr/u8-uctomb.c unistr/u8-uctomb-aux.c + +## end gnulib module unistr/u8-uctomb + +## begin gnulib module unitypes + + +EXTRA_DIST += unitypes.h + +## end gnulib module unitypes + +## begin gnulib module vasnprintf + + +EXTRA_DIST += asnprintf.c float+.h printf-args.c printf-args.h printf-parse.c printf-parse.h vasnprintf.c vasnprintf.h + +EXTRA_libgnu_la_SOURCES += asnprintf.c printf-args.c printf-parse.c vasnprintf.c + +## end gnulib module vasnprintf + ## begin gnulib module verify libgnu_la_SOURCES += verify.h ## end gnulib module verify +## begin gnulib module vsnprintf + + +EXTRA_DIST += vsnprintf.c + +EXTRA_libgnu_la_SOURCES += vsnprintf.c + +## end gnulib module vsnprintf + ## begin gnulib module wchar BUILT_SOURCES += $(WCHAR_H) @@ -455,6 +1098,7 @@ wchar.h: wchar.in.h -e 's|@''REPLACE_MBSNRTOWCS''@|$(REPLACE_MBSNRTOWCS)|g' \ -e 's|@''REPLACE_WCRTOMB''@|$(REPLACE_WCRTOMB)|g' \ -e 's|@''REPLACE_WCSRTOMBS''@|$(REPLACE_WCSRTOMBS)|g' \ + -e 's|@''REPLACE_WCSNRTOMBS''@|$(REPLACE_WCSNRTOMBS)|g' \ -e 's|@''REPLACE_WCWIDTH''@|$(REPLACE_WCWIDTH)|g' \ -e '/definition of GL_LINK_WARNING/r $(LINK_WARNING_H)' \ < $(srcdir)/wchar.in.h; \ @@ -475,6 +1119,12 @@ EXTRA_libgnu_la_SOURCES += write.c ## end gnulib module write +## begin gnulib module xsize + +libgnu_la_SOURCES += xsize.h + +## end gnulib module xsize + mostlyclean-local: mostlyclean-generic @for dir in '' $(MOSTLYCLEANDIRS); do \ diff --git a/lib/asnprintf.c b/lib/asnprintf.c new file mode 100644 index 000000000..3b374a2a4 --- /dev/null +++ b/lib/asnprintf.c @@ -0,0 +1,35 @@ +/* Formatted output to strings. + Copyright (C) 1999, 2002, 2006 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2, 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License along + with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include + +/* Specification. */ +#include "vasnprintf.h" + +#include + +char * +asnprintf (char *resultbuf, size_t *lengthp, const char *format, ...) +{ + va_list args; + char *result; + + va_start (args, format); + result = vasnprintf (resultbuf, lengthp, format, args); + va_end (args); + return result; +} diff --git a/lib/byteswap.in.h b/lib/byteswap.in.h new file mode 100644 index 000000000..f03463db6 --- /dev/null +++ b/lib/byteswap.in.h @@ -0,0 +1,44 @@ +/* byteswap.h - Byte swapping + Copyright (C) 2005, 2007 Free Software Foundation, Inc. + Written by Oskar Liljeblad , 2005. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#ifndef _GL_BYTESWAP_H +#define _GL_BYTESWAP_H + +/* Given an unsigned 16-bit argument X, return the value corresponding to + X with reversed byte order. */ +#define bswap_16(x) ((((x) & 0x00FF) << 8) | \ + (((x) & 0xFF00) >> 8)) + +/* Given an unsigned 32-bit argument X, return the value corresponding to + X with reversed byte order. */ +#define bswap_32(x) ((((x) & 0x000000FF) << 24) | \ + (((x) & 0x0000FF00) << 8) | \ + (((x) & 0x00FF0000) >> 8) | \ + (((x) & 0xFF000000) >> 24)) + +/* Given an unsigned 64-bit argument X, return the value corresponding to + X with reversed byte order. */ +#define bswap_64(x) ((((x) & 0x00000000000000FFULL) << 56) | \ + (((x) & 0x000000000000FF00ULL) << 40) | \ + (((x) & 0x0000000000FF0000ULL) << 24) | \ + (((x) & 0x00000000FF000000ULL) << 8) | \ + (((x) & 0x000000FF00000000ULL) >> 8) | \ + (((x) & 0x0000FF0000000000ULL) >> 24) | \ + (((x) & 0x00FF000000000000ULL) >> 40) | \ + (((x) & 0xFF00000000000000ULL) >> 56)) + +#endif /* _GL_BYTESWAP_H */ diff --git a/lib/c-ctype.c b/lib/c-ctype.c new file mode 100644 index 000000000..e36a51340 --- /dev/null +++ b/lib/c-ctype.c @@ -0,0 +1,396 @@ +/* Character handling in C locale. + + Copyright 2000-2003, 2006 Free Software Foundation, Inc. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This 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 Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program; if not, write to the Free Software Foundation, +Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include + +/* Specification. */ +#define NO_C_CTYPE_MACROS +#include "c-ctype.h" + +/* The function isascii is not locale dependent. Its use in EBCDIC is + questionable. */ +bool +c_isascii (int c) +{ + return (c >= 0x00 && c <= 0x7f); +} + +bool +c_isalnum (int c) +{ +#if C_CTYPE_CONSECUTIVE_DIGITS \ + && C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE +#if C_CTYPE_ASCII + return ((c >= '0' && c <= '9') + || ((c & ~0x20) >= 'A' && (c & ~0x20) <= 'Z')); +#else + return ((c >= '0' && c <= '9') + || (c >= 'A' && c <= 'Z') + || (c >= 'a' && c <= 'z')); +#endif +#else + switch (c) + { + case '0': case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': + case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': + case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': + case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': + case 'Y': case 'Z': + case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': + case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': + case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': + case 's': case 't': case 'u': case 'v': case 'w': case 'x': + case 'y': case 'z': + return 1; + default: + return 0; + } +#endif +} + +bool +c_isalpha (int c) +{ +#if C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE +#if C_CTYPE_ASCII + return ((c & ~0x20) >= 'A' && (c & ~0x20) <= 'Z'); +#else + return ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')); +#endif +#else + switch (c) + { + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': + case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': + case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': + case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': + case 'Y': case 'Z': + case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': + case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': + case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': + case 's': case 't': case 'u': case 'v': case 'w': case 'x': + case 'y': case 'z': + return 1; + default: + return 0; + } +#endif +} + +bool +c_isblank (int c) +{ + return (c == ' ' || c == '\t'); +} + +bool +c_iscntrl (int c) +{ +#if C_CTYPE_ASCII + return ((c & ~0x1f) == 0 || c == 0x7f); +#else + switch (c) + { + case ' ': case '!': case '"': case '#': case '$': case '%': + case '&': case '\'': case '(': case ')': case '*': case '+': + case ',': case '-': case '.': case '/': + case '0': case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': + case ':': case ';': case '<': case '=': case '>': case '?': + case '@': + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': + case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': + case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': + case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': + case 'Y': case 'Z': + case '[': case '\\': case ']': case '^': case '_': case '`': + case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': + case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': + case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': + case 's': case 't': case 'u': case 'v': case 'w': case 'x': + case 'y': case 'z': + case '{': case '|': case '}': case '~': + return 0; + default: + return 1; + } +#endif +} + +bool +c_isdigit (int c) +{ +#if C_CTYPE_CONSECUTIVE_DIGITS + return (c >= '0' && c <= '9'); +#else + switch (c) + { + case '0': case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': + return 1; + default: + return 0; + } +#endif +} + +bool +c_islower (int c) +{ +#if C_CTYPE_CONSECUTIVE_LOWERCASE + return (c >= 'a' && c <= 'z'); +#else + switch (c) + { + case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': + case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': + case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': + case 's': case 't': case 'u': case 'v': case 'w': case 'x': + case 'y': case 'z': + return 1; + default: + return 0; + } +#endif +} + +bool +c_isgraph (int c) +{ +#if C_CTYPE_ASCII + return (c >= '!' && c <= '~'); +#else + switch (c) + { + case '!': case '"': case '#': case '$': case '%': case '&': + case '\'': case '(': case ')': case '*': case '+': case ',': + case '-': case '.': case '/': + case '0': case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': + case ':': case ';': case '<': case '=': case '>': case '?': + case '@': + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': + case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': + case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': + case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': + case 'Y': case 'Z': + case '[': case '\\': case ']': case '^': case '_': case '`': + case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': + case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': + case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': + case 's': case 't': case 'u': case 'v': case 'w': case 'x': + case 'y': case 'z': + case '{': case '|': case '}': case '~': + return 1; + default: + return 0; + } +#endif +} + +bool +c_isprint (int c) +{ +#if C_CTYPE_ASCII + return (c >= ' ' && c <= '~'); +#else + switch (c) + { + case ' ': case '!': case '"': case '#': case '$': case '%': + case '&': case '\'': case '(': case ')': case '*': case '+': + case ',': case '-': case '.': case '/': + case '0': case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': + case ':': case ';': case '<': case '=': case '>': case '?': + case '@': + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': + case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': + case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': + case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': + case 'Y': case 'Z': + case '[': case '\\': case ']': case '^': case '_': case '`': + case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': + case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': + case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': + case 's': case 't': case 'u': case 'v': case 'w': case 'x': + case 'y': case 'z': + case '{': case '|': case '}': case '~': + return 1; + default: + return 0; + } +#endif +} + +bool +c_ispunct (int c) +{ +#if C_CTYPE_ASCII + return ((c >= '!' && c <= '~') + && !((c >= '0' && c <= '9') + || ((c & ~0x20) >= 'A' && (c & ~0x20) <= 'Z'))); +#else + switch (c) + { + case '!': case '"': case '#': case '$': case '%': case '&': + case '\'': case '(': case ')': case '*': case '+': case ',': + case '-': case '.': case '/': + case ':': case ';': case '<': case '=': case '>': case '?': + case '@': + case '[': case '\\': case ']': case '^': case '_': case '`': + case '{': case '|': case '}': case '~': + return 1; + default: + return 0; + } +#endif +} + +bool +c_isspace (int c) +{ + return (c == ' ' || c == '\t' + || c == '\n' || c == '\v' || c == '\f' || c == '\r'); +} + +bool +c_isupper (int c) +{ +#if C_CTYPE_CONSECUTIVE_UPPERCASE + return (c >= 'A' && c <= 'Z'); +#else + switch (c) + { + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': + case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': + case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': + case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': + case 'Y': case 'Z': + return 1; + default: + return 0; + } +#endif +} + +bool +c_isxdigit (int c) +{ +#if C_CTYPE_CONSECUTIVE_DIGITS \ + && C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE +#if C_CTYPE_ASCII + return ((c >= '0' && c <= '9') + || ((c & ~0x20) >= 'A' && (c & ~0x20) <= 'F')); +#else + return ((c >= '0' && c <= '9') + || (c >= 'A' && c <= 'F') + || (c >= 'a' && c <= 'f')); +#endif +#else + switch (c) + { + case '0': case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': + case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': + return 1; + default: + return 0; + } +#endif +} + +int +c_tolower (int c) +{ +#if C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE + return (c >= 'A' && c <= 'Z' ? c - 'A' + 'a' : c); +#else + switch (c) + { + case 'A': return 'a'; + case 'B': return 'b'; + case 'C': return 'c'; + case 'D': return 'd'; + case 'E': return 'e'; + case 'F': return 'f'; + case 'G': return 'g'; + case 'H': return 'h'; + case 'I': return 'i'; + case 'J': return 'j'; + case 'K': return 'k'; + case 'L': return 'l'; + case 'M': return 'm'; + case 'N': return 'n'; + case 'O': return 'o'; + case 'P': return 'p'; + case 'Q': return 'q'; + case 'R': return 'r'; + case 'S': return 's'; + case 'T': return 't'; + case 'U': return 'u'; + case 'V': return 'v'; + case 'W': return 'w'; + case 'X': return 'x'; + case 'Y': return 'y'; + case 'Z': return 'z'; + default: return c; + } +#endif +} + +int +c_toupper (int c) +{ +#if C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE + return (c >= 'a' && c <= 'z' ? c - 'a' + 'A' : c); +#else + switch (c) + { + case 'a': return 'A'; + case 'b': return 'B'; + case 'c': return 'C'; + case 'd': return 'D'; + case 'e': return 'E'; + case 'f': return 'F'; + case 'g': return 'G'; + case 'h': return 'H'; + case 'i': return 'I'; + case 'j': return 'J'; + case 'k': return 'K'; + case 'l': return 'L'; + case 'm': return 'M'; + case 'n': return 'N'; + case 'o': return 'O'; + case 'p': return 'P'; + case 'q': return 'Q'; + case 'r': return 'R'; + case 's': return 'S'; + case 't': return 'T'; + case 'u': return 'U'; + case 'v': return 'V'; + case 'w': return 'W'; + case 'x': return 'X'; + case 'y': return 'Y'; + case 'z': return 'Z'; + default: return c; + } +#endif +} diff --git a/lib/c-ctype.h b/lib/c-ctype.h new file mode 100644 index 000000000..d7b067e83 --- /dev/null +++ b/lib/c-ctype.h @@ -0,0 +1,295 @@ +/* Character handling in C locale. + + These functions work like the corresponding functions in , + except that they have the C (POSIX) locale hardwired, whereas the + functions' behaviour depends on the current locale set via + setlocale. + + Copyright (C) 2000-2003, 2006, 2008 Free Software Foundation, Inc. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This 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 Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program; if not, write to the Free Software Foundation, +Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef C_CTYPE_H +#define C_CTYPE_H + +#include + + +#ifdef __cplusplus +extern "C" { +#endif + + +/* The functions defined in this file assume the "C" locale and a character + set without diacritics (ASCII-US or EBCDIC-US or something like that). + Even if the "C" locale on a particular system is an extension of the ASCII + character set (like on BeOS, where it is UTF-8, or on AmigaOS, where it + is ISO-8859-1), the functions in this file recognize only the ASCII + characters. */ + + +/* Check whether the ASCII optimizations apply. */ + +/* ANSI C89 (and ISO C99 5.2.1.3 too) already guarantees that + '0', '1', ..., '9' have consecutive integer values. */ +#define C_CTYPE_CONSECUTIVE_DIGITS 1 + +#if ('A' <= 'Z') \ + && ('A' + 1 == 'B') && ('B' + 1 == 'C') && ('C' + 1 == 'D') \ + && ('D' + 1 == 'E') && ('E' + 1 == 'F') && ('F' + 1 == 'G') \ + && ('G' + 1 == 'H') && ('H' + 1 == 'I') && ('I' + 1 == 'J') \ + && ('J' + 1 == 'K') && ('K' + 1 == 'L') && ('L' + 1 == 'M') \ + && ('M' + 1 == 'N') && ('N' + 1 == 'O') && ('O' + 1 == 'P') \ + && ('P' + 1 == 'Q') && ('Q' + 1 == 'R') && ('R' + 1 == 'S') \ + && ('S' + 1 == 'T') && ('T' + 1 == 'U') && ('U' + 1 == 'V') \ + && ('V' + 1 == 'W') && ('W' + 1 == 'X') && ('X' + 1 == 'Y') \ + && ('Y' + 1 == 'Z') +#define C_CTYPE_CONSECUTIVE_UPPERCASE 1 +#endif + +#if ('a' <= 'z') \ + && ('a' + 1 == 'b') && ('b' + 1 == 'c') && ('c' + 1 == 'd') \ + && ('d' + 1 == 'e') && ('e' + 1 == 'f') && ('f' + 1 == 'g') \ + && ('g' + 1 == 'h') && ('h' + 1 == 'i') && ('i' + 1 == 'j') \ + && ('j' + 1 == 'k') && ('k' + 1 == 'l') && ('l' + 1 == 'm') \ + && ('m' + 1 == 'n') && ('n' + 1 == 'o') && ('o' + 1 == 'p') \ + && ('p' + 1 == 'q') && ('q' + 1 == 'r') && ('r' + 1 == 's') \ + && ('s' + 1 == 't') && ('t' + 1 == 'u') && ('u' + 1 == 'v') \ + && ('v' + 1 == 'w') && ('w' + 1 == 'x') && ('x' + 1 == 'y') \ + && ('y' + 1 == 'z') +#define C_CTYPE_CONSECUTIVE_LOWERCASE 1 +#endif + +#if (' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ + && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ + && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ + && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ + && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ + && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ + && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ + && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ + && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ + && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ + && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ + && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ + && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ + && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ + && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ + && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ + && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ + && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ + && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ + && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ + && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ + && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ + && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126) +/* The character set is ASCII or one of its variants or extensions, not EBCDIC. + Testing the value of '\n' and '\r' is not relevant. */ +#define C_CTYPE_ASCII 1 +#endif + + +/* Function declarations. */ + +/* Unlike the functions in , which require an argument in the range + of the 'unsigned char' type, the functions here operate on values that are + in the 'unsigned char' range or in the 'char' range. In other words, + when you have a 'char' value, you need to cast it before using it as + argument to a function: + + const char *s = ...; + if (isalpha ((unsigned char) *s)) ... + + but you don't need to cast it for the functions defined in this file: + + const char *s = ...; + if (c_isalpha (*s)) ... + */ + +extern bool c_isascii (int c); /* not locale dependent */ + +extern bool c_isalnum (int c); +extern bool c_isalpha (int c); +extern bool c_isblank (int c); +extern bool c_iscntrl (int c); +extern bool c_isdigit (int c); +extern bool c_islower (int c); +extern bool c_isgraph (int c); +extern bool c_isprint (int c); +extern bool c_ispunct (int c); +extern bool c_isspace (int c); +extern bool c_isupper (int c); +extern bool c_isxdigit (int c); + +extern int c_tolower (int c); +extern int c_toupper (int c); + + +#if defined __GNUC__ && defined __OPTIMIZE__ && !defined __OPTIMIZE_SIZE__ && !defined NO_C_CTYPE_MACROS + +/* ASCII optimizations. */ + +#undef c_isascii +#define c_isascii(c) \ + ({ int __c = (c); \ + (__c >= 0x00 && __c <= 0x7f); \ + }) + +#if C_CTYPE_CONSECUTIVE_DIGITS \ + && C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE +#if C_CTYPE_ASCII +#undef c_isalnum +#define c_isalnum(c) \ + ({ int __c = (c); \ + ((__c >= '0' && __c <= '9') \ + || ((__c & ~0x20) >= 'A' && (__c & ~0x20) <= 'Z')); \ + }) +#else +#undef c_isalnum +#define c_isalnum(c) \ + ({ int __c = (c); \ + ((__c >= '0' && __c <= '9') \ + || (__c >= 'A' && __c <= 'Z') \ + || (__c >= 'a' && __c <= 'z')); \ + }) +#endif +#endif + +#if C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE +#if C_CTYPE_ASCII +#undef c_isalpha +#define c_isalpha(c) \ + ({ int __c = (c); \ + ((__c & ~0x20) >= 'A' && (__c & ~0x20) <= 'Z'); \ + }) +#else +#undef c_isalpha +#define c_isalpha(c) \ + ({ int __c = (c); \ + ((__c >= 'A' && __c <= 'Z') || (__c >= 'a' && __c <= 'z')); \ + }) +#endif +#endif + +#undef c_isblank +#define c_isblank(c) \ + ({ int __c = (c); \ + (__c == ' ' || __c == '\t'); \ + }) + +#if C_CTYPE_ASCII +#undef c_iscntrl +#define c_iscntrl(c) \ + ({ int __c = (c); \ + ((__c & ~0x1f) == 0 || __c == 0x7f); \ + }) +#endif + +#if C_CTYPE_CONSECUTIVE_DIGITS +#undef c_isdigit +#define c_isdigit(c) \ + ({ int __c = (c); \ + (__c >= '0' && __c <= '9'); \ + }) +#endif + +#if C_CTYPE_CONSECUTIVE_LOWERCASE +#undef c_islower +#define c_islower(c) \ + ({ int __c = (c); \ + (__c >= 'a' && __c <= 'z'); \ + }) +#endif + +#if C_CTYPE_ASCII +#undef c_isgraph +#define c_isgraph(c) \ + ({ int __c = (c); \ + (__c >= '!' && __c <= '~'); \ + }) +#endif + +#if C_CTYPE_ASCII +#undef c_isprint +#define c_isprint(c) \ + ({ int __c = (c); \ + (__c >= ' ' && __c <= '~'); \ + }) +#endif + +#if C_CTYPE_ASCII +#undef c_ispunct +#define c_ispunct(c) \ + ({ int _c = (c); \ + (c_isgraph (_c) && ! c_isalnum (_c)); \ + }) +#endif + +#undef c_isspace +#define c_isspace(c) \ + ({ int __c = (c); \ + (__c == ' ' || __c == '\t' \ + || __c == '\n' || __c == '\v' || __c == '\f' || __c == '\r'); \ + }) + +#if C_CTYPE_CONSECUTIVE_UPPERCASE +#undef c_isupper +#define c_isupper(c) \ + ({ int __c = (c); \ + (__c >= 'A' && __c <= 'Z'); \ + }) +#endif + +#if C_CTYPE_CONSECUTIVE_DIGITS \ + && C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE +#if C_CTYPE_ASCII +#undef c_isxdigit +#define c_isxdigit(c) \ + ({ int __c = (c); \ + ((__c >= '0' && __c <= '9') \ + || ((__c & ~0x20) >= 'A' && (__c & ~0x20) <= 'F')); \ + }) +#else +#undef c_isxdigit +#define c_isxdigit(c) \ + ({ int __c = (c); \ + ((__c >= '0' && __c <= '9') \ + || (__c >= 'A' && __c <= 'F') \ + || (__c >= 'a' && __c <= 'f')); \ + }) +#endif +#endif + +#if C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE +#undef c_tolower +#define c_tolower(c) \ + ({ int __c = (c); \ + (__c >= 'A' && __c <= 'Z' ? __c - 'A' + 'a' : __c); \ + }) +#undef c_toupper +#define c_toupper(c) \ + ({ int __c = (c); \ + (__c >= 'a' && __c <= 'z' ? __c - 'a' + 'A' : __c); \ + }) +#endif + +#endif /* optimizing for speed */ + + +#ifdef __cplusplus +} +#endif + +#endif /* C_CTYPE_H */ diff --git a/lib/c-strcase.h b/lib/c-strcase.h new file mode 100644 index 000000000..714a3c623 --- /dev/null +++ b/lib/c-strcase.h @@ -0,0 +1,55 @@ +/* Case-insensitive string comparison functions in C locale. + Copyright (C) 1995-1996, 2001, 2003, 2005 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2, 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef C_STRCASE_H +#define C_STRCASE_H + +#include + + +/* The functions defined in this file assume the "C" locale and a character + set without diacritics (ASCII-US or EBCDIC-US or something like that). + Even if the "C" locale on a particular system is an extension of the ASCII + character set (like on BeOS, where it is UTF-8, or on AmigaOS, where it + is ISO-8859-1), the functions in this file recognize only the ASCII + characters. More precisely, one of the string arguments must be an ASCII + string; the other one can also contain non-ASCII characters (but then + the comparison result will be nonzero). */ + + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Compare strings S1 and S2, ignoring case, returning less than, equal to or + greater than zero if S1 is lexicographically less than, equal to or greater + than S2. */ +extern int c_strcasecmp (const char *s1, const char *s2); + +/* Compare no more than N characters of strings S1 and S2, ignoring case, + returning less than, equal to or greater than zero if S1 is + lexicographically less than, equal to or greater than S2. */ +extern int c_strncasecmp (const char *s1, const char *s2, size_t n); + + +#ifdef __cplusplus +} +#endif + + +#endif /* C_STRCASE_H */ diff --git a/lib/c-strcasecmp.c b/lib/c-strcasecmp.c new file mode 100644 index 000000000..a52389883 --- /dev/null +++ b/lib/c-strcasecmp.c @@ -0,0 +1,57 @@ +/* c-strcasecmp.c -- case insensitive string comparator in C locale + Copyright (C) 1998-1999, 2005-2006 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2, 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include + +/* Specification. */ +#include "c-strcase.h" + +#include + +#include "c-ctype.h" + +int +c_strcasecmp (const char *s1, const char *s2) +{ + register const unsigned char *p1 = (const unsigned char *) s1; + register const unsigned char *p2 = (const unsigned char *) s2; + unsigned char c1, c2; + + if (p1 == p2) + return 0; + + do + { + c1 = c_tolower (*p1); + c2 = c_tolower (*p2); + + if (c1 == '\0') + break; + + ++p1; + ++p2; + } + while (c1 == c2); + + if (UCHAR_MAX <= INT_MAX) + return c1 - c2; + else + /* On machines where 'char' and 'int' are types of the same size, the + difference of two 'unsigned char' values - including the sign bit - + doesn't fit in an 'int'. */ + return (c1 > c2 ? 1 : c1 < c2 ? -1 : 0); +} diff --git a/lib/c-strcaseeq.h b/lib/c-strcaseeq.h new file mode 100644 index 000000000..cd29b66c7 --- /dev/null +++ b/lib/c-strcaseeq.h @@ -0,0 +1,184 @@ +/* Optimized case-insensitive string comparison in C locale. + Copyright (C) 2001-2002, 2007 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +/* Written by Bruno Haible . */ + +#include "c-strcase.h" +#include "c-ctype.h" + +/* STRCASEEQ allows to optimize string comparison with a small literal string. + STRCASEEQ (s, "UTF-8", 'U','T','F','-','8',0,0,0,0) + is semantically equivalent to + c_strcasecmp (s, "UTF-8") == 0 + just faster. */ + +/* Help GCC to generate good code for string comparisons with + immediate strings. */ +#if defined (__GNUC__) && defined (__OPTIMIZE__) + +/* Case insensitive comparison of ASCII characters. */ +# if C_CTYPE_ASCII +# define CASEEQ(other,upper) \ + (c_isupper (upper) ? ((other) & ~0x20) == (upper) : (other) == (upper)) +# elif C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE +# define CASEEQ(other,upper) \ + (c_isupper (upper) ? (other) == (upper) || (other) == (upper) - 'A' + 'a' : (other) == (upper)) +# else +# define CASEEQ(other,upper) \ + (c_toupper (other) == (upper)) +# endif + +static inline int +strcaseeq9 (const char *s1, const char *s2) +{ + return c_strcasecmp (s1 + 9, s2 + 9) == 0; +} + +static inline int +strcaseeq8 (const char *s1, const char *s2, char s28) +{ + if (CASEEQ (s1[8], s28)) + { + if (s28 == 0) + return 1; + else + return strcaseeq9 (s1, s2); + } + else + return 0; +} + +static inline int +strcaseeq7 (const char *s1, const char *s2, char s27, char s28) +{ + if (CASEEQ (s1[7], s27)) + { + if (s27 == 0) + return 1; + else + return strcaseeq8 (s1, s2, s28); + } + else + return 0; +} + +static inline int +strcaseeq6 (const char *s1, const char *s2, char s26, char s27, char s28) +{ + if (CASEEQ (s1[6], s26)) + { + if (s26 == 0) + return 1; + else + return strcaseeq7 (s1, s2, s27, s28); + } + else + return 0; +} + +static inline int +strcaseeq5 (const char *s1, const char *s2, char s25, char s26, char s27, char s28) +{ + if (CASEEQ (s1[5], s25)) + { + if (s25 == 0) + return 1; + else + return strcaseeq6 (s1, s2, s26, s27, s28); + } + else + return 0; +} + +static inline int +strcaseeq4 (const char *s1, const char *s2, char s24, char s25, char s26, char s27, char s28) +{ + if (CASEEQ (s1[4], s24)) + { + if (s24 == 0) + return 1; + else + return strcaseeq5 (s1, s2, s25, s26, s27, s28); + } + else + return 0; +} + +static inline int +strcaseeq3 (const char *s1, const char *s2, char s23, char s24, char s25, char s26, char s27, char s28) +{ + if (CASEEQ (s1[3], s23)) + { + if (s23 == 0) + return 1; + else + return strcaseeq4 (s1, s2, s24, s25, s26, s27, s28); + } + else + return 0; +} + +static inline int +strcaseeq2 (const char *s1, const char *s2, char s22, char s23, char s24, char s25, char s26, char s27, char s28) +{ + if (CASEEQ (s1[2], s22)) + { + if (s22 == 0) + return 1; + else + return strcaseeq3 (s1, s2, s23, s24, s25, s26, s27, s28); + } + else + return 0; +} + +static inline int +strcaseeq1 (const char *s1, const char *s2, char s21, char s22, char s23, char s24, char s25, char s26, char s27, char s28) +{ + if (CASEEQ (s1[1], s21)) + { + if (s21 == 0) + return 1; + else + return strcaseeq2 (s1, s2, s22, s23, s24, s25, s26, s27, s28); + } + else + return 0; +} + +static inline int +strcaseeq0 (const char *s1, const char *s2, char s20, char s21, char s22, char s23, char s24, char s25, char s26, char s27, char s28) +{ + if (CASEEQ (s1[0], s20)) + { + if (s20 == 0) + return 1; + else + return strcaseeq1 (s1, s2, s21, s22, s23, s24, s25, s26, s27, s28); + } + else + return 0; +} + +#define STRCASEEQ(s1,s2,s20,s21,s22,s23,s24,s25,s26,s27,s28) \ + strcaseeq0 (s1, s2, s20, s21, s22, s23, s24, s25, s26, s27, s28) + +#else + +#define STRCASEEQ(s1,s2,s20,s21,s22,s23,s24,s25,s26,s27,s28) \ + (c_strcasecmp (s1, s2) == 0) + +#endif diff --git a/lib/c-strncasecmp.c b/lib/c-strncasecmp.c new file mode 100644 index 000000000..c1496ca41 --- /dev/null +++ b/lib/c-strncasecmp.c @@ -0,0 +1,57 @@ +/* c-strncasecmp.c -- case insensitive string comparator in C locale + Copyright (C) 1998-1999, 2005-2006 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2, 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include + +/* Specification. */ +#include "c-strcase.h" + +#include + +#include "c-ctype.h" + +int +c_strncasecmp (const char *s1, const char *s2, size_t n) +{ + register const unsigned char *p1 = (const unsigned char *) s1; + register const unsigned char *p2 = (const unsigned char *) s2; + unsigned char c1, c2; + + if (p1 == p2 || n == 0) + return 0; + + do + { + c1 = c_tolower (*p1); + c2 = c_tolower (*p2); + + if (--n == 0 || c1 == '\0') + break; + + ++p1; + ++p2; + } + while (c1 == c2); + + if (UCHAR_MAX <= INT_MAX) + return c1 - c2; + else + /* On machines where 'char' and 'int' are types of the same size, the + difference of two 'unsigned char' values - including the sign bit - + doesn't fit in an 'int'. */ + return (c1 > c2 ? 1 : c1 < c2 ? -1 : 0); +} diff --git a/lib/canonicalize-lgpl.c b/lib/canonicalize-lgpl.c new file mode 100644 index 000000000..8bc24680f --- /dev/null +++ b/lib/canonicalize-lgpl.c @@ -0,0 +1,362 @@ +/* Return the canonical absolute name of a given file. + Copyright (C) 1996-2003, 2005-2008 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#include + +/* Avoid a clash of our rpl_realpath() function with the prototype in + on Solaris 2.5.1. */ +#undef realpath + +#if !HAVE_CANONICALIZE_FILE_NAME || defined _LIBC + +#include + +/* Specification. */ +#include "canonicalize.h" + +#include +#include +#include + +#if HAVE_UNISTD_H || defined _LIBC +# include +#endif + +#include + +#if HAVE_SYS_PARAM_H || defined _LIBC +# include +#endif +#ifndef MAXSYMLINKS +# define MAXSYMLINKS 20 +#endif + +#include + +#include +#ifndef _LIBC +# define __set_errno(e) errno = (e) +# ifndef ENAMETOOLONG +# define ENAMETOOLONG EINVAL +# endif +#endif + +#ifdef _LIBC +# include +#else +# define SHLIB_COMPAT(lib, introduced, obsoleted) 0 +# define versioned_symbol(lib, local, symbol, version) +# define compat_symbol(lib, local, symbol, version) +# define weak_alias(local, symbol) +# define __canonicalize_file_name canonicalize_file_name +# define __realpath rpl_realpath +# include "pathmax.h" +# include "malloca.h" +# if HAVE_GETCWD +# ifdef VMS + /* We want the directory in Unix syntax, not in VMS syntax. */ +# define __getcwd(buf, max) getcwd (buf, max, 0) +# else +# define __getcwd getcwd +# endif +# else +# define __getcwd(buf, max) getwd (buf) +# endif +# define __readlink readlink + /* On systems without symbolic links, call stat() instead of lstat(). */ +# if !defined S_ISLNK && !HAVE_READLINK +# define lstat stat +# endif +#endif + +/* Return the canonical absolute name of file NAME. A canonical name + does not contain any `.', `..' components nor any repeated path + separators ('/') or symlinks. All path components must exist. If + RESOLVED is null, the result is malloc'd; otherwise, if the + canonical name is PATH_MAX chars or more, returns null with `errno' + set to ENAMETOOLONG; if the name fits in fewer than PATH_MAX chars, + returns the name in RESOLVED. If the name cannot be resolved and + RESOLVED is non-NULL, it contains the path of the first component + that cannot be resolved. If the path can be resolved, RESOLVED + holds the same value as the value returned. */ + +char * +__realpath (const char *name, char *resolved) +{ + char *rpath, *dest, *extra_buf = NULL; + const char *start, *end, *rpath_limit; + long int path_max; +#if HAVE_READLINK + int num_links = 0; +#endif + + if (name == NULL) + { + /* As per Single Unix Specification V2 we must return an error if + either parameter is a null pointer. We extend this to allow + the RESOLVED parameter to be NULL in case the we are expected to + allocate the room for the return value. */ + __set_errno (EINVAL); + return NULL; + } + + if (name[0] == '\0') + { + /* As per Single Unix Specification V2 we must return an error if + the name argument points to an empty string. */ + __set_errno (ENOENT); + return NULL; + } + +#ifdef PATH_MAX + path_max = PATH_MAX; +#else + path_max = pathconf (name, _PC_PATH_MAX); + if (path_max <= 0) + path_max = 1024; +#endif + + if (resolved == NULL) + { + rpath = malloc (path_max); + if (rpath == NULL) + { + /* It's easier to set errno to ENOMEM than to rely on the + 'malloc-posix' gnulib module. */ + errno = ENOMEM; + return NULL; + } + } + else + rpath = resolved; + rpath_limit = rpath + path_max; + + if (name[0] != '/') + { + if (!__getcwd (rpath, path_max)) + { + rpath[0] = '\0'; + goto error; + } + dest = strchr (rpath, '\0'); + } + else + { + rpath[0] = '/'; + dest = rpath + 1; + } + + for (start = end = name; *start; start = end) + { +#ifdef _LIBC + struct stat64 st; +#else + struct stat st; +#endif + + /* Skip sequence of multiple path-separators. */ + while (*start == '/') + ++start; + + /* Find end of path component. */ + for (end = start; *end && *end != '/'; ++end) + /* Nothing. */; + + if (end - start == 0) + break; + else if (end - start == 1 && start[0] == '.') + /* nothing */; + else if (end - start == 2 && start[0] == '.' && start[1] == '.') + { + /* Back up to previous component, ignore if at root already. */ + if (dest > rpath + 1) + while ((--dest)[-1] != '/'); + } + else + { + size_t new_size; + + if (dest[-1] != '/') + *dest++ = '/'; + + if (dest + (end - start) >= rpath_limit) + { + ptrdiff_t dest_offset = dest - rpath; + char *new_rpath; + + if (resolved) + { + __set_errno (ENAMETOOLONG); + if (dest > rpath + 1) + dest--; + *dest = '\0'; + goto error; + } + new_size = rpath_limit - rpath; + if (end - start + 1 > path_max) + new_size += end - start + 1; + else + new_size += path_max; + new_rpath = (char *) realloc (rpath, new_size); + if (new_rpath == NULL) + { + /* It's easier to set errno to ENOMEM than to rely on the + 'realloc-posix' gnulib module. */ + errno = ENOMEM; + goto error; + } + rpath = new_rpath; + rpath_limit = rpath + new_size; + + dest = rpath + dest_offset; + } + +#ifdef _LIBC + dest = __mempcpy (dest, start, end - start); +#else + memcpy (dest, start, end - start); + dest += end - start; +#endif + *dest = '\0'; + +#ifdef _LIBC + if (__lxstat64 (_STAT_VER, rpath, &st) < 0) +#else + if (lstat (rpath, &st) < 0) +#endif + goto error; + +#if HAVE_READLINK + if (S_ISLNK (st.st_mode)) + { + char *buf; + size_t len; + int n; + + if (++num_links > MAXSYMLINKS) + { + __set_errno (ELOOP); + goto error; + } + + buf = malloca (path_max); + if (!buf) + { + errno = ENOMEM; + goto error; + } + + n = __readlink (rpath, buf, path_max - 1); + if (n < 0) + { + int saved_errno = errno; + freea (buf); + errno = saved_errno; + goto error; + } + buf[n] = '\0'; + + if (!extra_buf) + { + extra_buf = malloca (path_max); + if (!extra_buf) + { + freea (buf); + errno = ENOMEM; + goto error; + } + } + + len = strlen (end); + if ((long int) (n + len) >= path_max) + { + freea (buf); + __set_errno (ENAMETOOLONG); + goto error; + } + + /* Careful here, end may be a pointer into extra_buf... */ + memmove (&extra_buf[n], end, len + 1); + name = end = memcpy (extra_buf, buf, n); + + if (buf[0] == '/') + dest = rpath + 1; /* It's an absolute symlink */ + else + /* Back up to previous component, ignore if at root already: */ + if (dest > rpath + 1) + while ((--dest)[-1] != '/'); + } +#endif + } + } + if (dest > rpath + 1 && dest[-1] == '/') + --dest; + *dest = '\0'; + + if (extra_buf) + freea (extra_buf); + + return resolved ? memcpy (resolved, rpath, dest - rpath + 1) : rpath; + +error: + { + int saved_errno = errno; + if (extra_buf) + freea (extra_buf); + if (resolved) + strcpy (resolved, rpath); + else + free (rpath); + errno = saved_errno; + } + return NULL; +} +#ifdef _LIBC +versioned_symbol (libc, __realpath, realpath, GLIBC_2_3); +#endif + + +#if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_3) +char * +__old_realpath (const char *name, char *resolved) +{ + if (resolved == NULL) + { + __set_errno (EINVAL); + return NULL; + } + + return __realpath (name, resolved); +} +compat_symbol (libc, __old_realpath, realpath, GLIBC_2_0); +#endif + + +char * +__canonicalize_file_name (const char *name) +{ + return __realpath (name, NULL); +} +weak_alias (__canonicalize_file_name, canonicalize_file_name) + +#else + +/* This declaration is solely to ensure that after preprocessing + this file is never empty. */ +typedef int dummy; + +#endif diff --git a/lib/canonicalize.h b/lib/canonicalize.h new file mode 100644 index 000000000..184cf1637 --- /dev/null +++ b/lib/canonicalize.h @@ -0,0 +1,52 @@ +/* Return the canonical absolute name of a given file. + Copyright (C) 1996-2007 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#ifndef CANONICALIZE_H_ +# define CANONICALIZE_H_ + +# if GNULIB_CANONICALIZE +enum canonicalize_mode_t + { + /* All components must exist. */ + CAN_EXISTING = 0, + + /* All components excluding last one must exist. */ + CAN_ALL_BUT_LAST = 1, + + /* No requirements on components existence. */ + CAN_MISSING = 2 + }; +typedef enum canonicalize_mode_t canonicalize_mode_t; + +/* Return a malloc'd string containing the canonical absolute name of + the named file. This acts like canonicalize_file_name, except that + whether components must exist depends on the canonicalize_mode_t + argument. */ +char *canonicalize_filename_mode (const char *, canonicalize_mode_t); +# endif + +# if HAVE_DECL_CANONICALIZE_FILE_NAME +# include +# else +/* Return a malloc'd string containing the canonical absolute name of + the named file. If any file name component does not exist or is a + symlink to a nonexistent file, return NULL. A canonical name does + not contain any `.', `..' components nor any repeated file name + separators ('/') or symlinks. */ +char *canonicalize_file_name (const char *); +# endif + +#endif /* !CANONICALIZE_H_ */ diff --git a/lib/config.charset b/lib/config.charset index 50b4406b2..c1a7f5dbb 100755 --- a/lib/config.charset +++ b/lib/config.charset @@ -1,7 +1,7 @@ #! /bin/sh # Output a system dependent table of character encoding aliases. # -# Copyright (C) 2000-2004, 2006-2008 Free Software Foundation, Inc. +# Copyright (C) 2000-2004, 2006-2009 Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by @@ -63,12 +63,13 @@ # CP922 aix # CP932 aix woe32 dos # CP943 aix -# CP949 osf woe32 dos +# CP949 osf darwin woe32 dos # CP950 woe32 dos # CP1046 aix # CP1124 aix # CP1125 dos # CP1129 aix +# CP1131 darwin # CP1250 woe32 # CP1251 glibc solaris netbsd openbsd darwin woe32 # CP1252 aix woe32 @@ -82,15 +83,17 @@ # EUC-KR Y glibc aix hpux irix osf solaris freebsd netbsd darwin # EUC-TW glibc aix hpux irix osf solaris netbsd # BIG5 Y glibc aix hpux osf solaris freebsd netbsd darwin -# BIG5-HKSCS glibc solaris -# GBK glibc aix osf solaris woe32 dos -# GB18030 glibc solaris netbsd +# BIG5-HKSCS glibc solaris darwin +# GBK glibc aix osf solaris darwin woe32 dos +# GB18030 glibc solaris netbsd darwin # SHIFT_JIS Y hpux osf solaris freebsd netbsd darwin # JOHAB glibc solaris woe32 # TIS-620 glibc aix hpux osf solaris # VISCII Y glibc # TCVN5712-1 glibc +# ARMSCII-8 glibc darwin # GEORGIAN-PS glibc +# PT154 glibc # HP-ROMAN8 hpux # HP-ARABIC8 hpux # HP-GREEK8 hpux @@ -449,7 +452,8 @@ case "$os" in echo "ko_KR.EUC EUC-KR" ;; darwin*) - # Darwin 7.5 has nl_langinfo(CODESET), but it is useless: + # Darwin 7.5 has nl_langinfo(CODESET), but sometimes its value is + # useless: # - It returns the empty string when LANG is set to a locale of the # form ll_CC, although ll_CC/LC_CTYPE is a symlink to an UTF-8 # LC_CTYPE file. @@ -476,6 +480,36 @@ case "$os" in # minimize the use of decomposed Unicode. Unfortunately, through the # Darwin file system, decomposed UTF-8 strings are leaked into user # space nevertheless. + # Then there are also the locales with encodings other than US-ASCII + # and UTF-8. These locales can be occasionally useful to users (e.g. + # when grepping through ISO-8859-1 encoded text files), when all their + # file names are in US-ASCII. + echo "ISO8859-1 ISO-8859-1" + echo "ISO8859-2 ISO-8859-2" + echo "ISO8859-4 ISO-8859-4" + echo "ISO8859-5 ISO-8859-5" + echo "ISO8859-7 ISO-8859-7" + echo "ISO8859-9 ISO-8859-9" + echo "ISO8859-13 ISO-8859-13" + echo "ISO8859-15 ISO-8859-15" + echo "KOI8-R KOI8-R" + echo "KOI8-U KOI8-U" + echo "CP866 CP866" + echo "CP949 CP949" + echo "CP1131 CP1131" + echo "CP1251 CP1251" + echo "eucCN GB2312" + echo "GB2312 GB2312" + echo "eucJP EUC-JP" + echo "eucKR EUC-KR" + echo "Big5 BIG5" + echo "Big5HKSCS BIG5-HKSCS" + echo "GBK GBK" + echo "GB18030 GB18030" + echo "SJIS SHIFT_JIS" + echo "ARMSCII-8 ARMSCII-8" + echo "PT154 PT154" + #echo "ISCII-DEV ?" echo "* UTF-8" ;; beos* | haiku*) diff --git a/lib/errno.in.h b/lib/errno.in.h new file mode 100644 index 000000000..a9b81d5df --- /dev/null +++ b/lib/errno.in.h @@ -0,0 +1,160 @@ +/* A POSIX-like . + + Copyright (C) 2008-2009 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2, 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef _GL_ERRNO_H + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif + +/* The include_next requires a split double-inclusion guard. */ +#@INCLUDE_NEXT@ @NEXT_ERRNO_H@ + +#ifndef _GL_ERRNO_H +#define _GL_ERRNO_H + + +/* On native Windows platforms, many macros are not defined. */ +# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ + +/* POSIX says that EAGAIN and EWOULDBLOCK may have the same value. */ +# define EWOULDBLOCK EAGAIN + +/* Values >= 100 seem safe to use. */ +# define ETXTBSY 100 +# define GNULIB_defined_ETXTBSY 1 + +/* These are intentionally the same values as the WSA* error numbers, defined + in . */ +# define EINPROGRESS 10036 +# define EALREADY 10037 +# define ENOTSOCK 10038 +# define EDESTADDRREQ 10039 +# define EMSGSIZE 10040 +# define EPROTOTYPE 10041 +# define ENOPROTOOPT 10042 +# define EPROTONOSUPPORT 10043 +# define ESOCKTNOSUPPORT 10044 /* not required by POSIX */ +# define EOPNOTSUPP 10045 +# define EPFNOSUPPORT 10046 /* not required by POSIX */ +# define EAFNOSUPPORT 10047 +# define EADDRINUSE 10048 +# define EADDRNOTAVAIL 10049 +# define ENETDOWN 10050 +# define ENETUNREACH 10051 +# define ENETRESET 10052 +# define ECONNABORTED 10053 +# define ECONNRESET 10054 +# define ENOBUFS 10055 +# define EISCONN 10056 +# define ENOTCONN 10057 +# define ESHUTDOWN 10058 /* not required by POSIX */ +# define ETOOMANYREFS 10059 /* not required by POSIX */ +# define ETIMEDOUT 10060 +# define ECONNREFUSED 10061 +# define ELOOP 10062 +# define EHOSTDOWN 10064 /* not required by POSIX */ +# define EHOSTUNREACH 10065 +# define EPROCLIM 10067 /* not required by POSIX */ +# define EUSERS 10068 /* not required by POSIX */ +# define EDQUOT 10069 +# define ESTALE 10070 +# define EREMOTE 10071 /* not required by POSIX */ +# define GNULIB_defined_ESOCK 1 + +# endif + + +/* On OSF/1 5.1, when _XOPEN_SOURCE_EXTENDED is not defined, the macros + EMULTIHOP, ENOLINK, EOVERFLOW are not defined. */ +# if @EMULTIHOP_HIDDEN@ +# define EMULTIHOP @EMULTIHOP_VALUE@ +# define GNULIB_defined_EMULTIHOP 1 +# endif +# if @ENOLINK_HIDDEN@ +# define ENOLINK @ENOLINK_VALUE@ +# define GNULIB_defined_ENOLINK 1 +# endif +# if @EOVERFLOW_HIDDEN@ +# define EOVERFLOW @EOVERFLOW_VALUE@ +# define GNULIB_defined_EOVERFLOW 1 +# endif + + +/* On OpenBSD 4.0 and on native Windows, the macros ENOMSG, EIDRM, ENOLINK, + EPROTO, EMULTIHOP, EBADMSG, EOVERFLOW, ENOTSUP, ECANCELED are not defined. + Define them here. Values >= 2000 seem safe to use: Solaris ESTALE = 151, + HP-UX EWOULDBLOCK = 246, IRIX EDQUOT = 1133. + + Note: When one of these systems defines some of these macros some day, + binaries will have to be recompiled so that they recognizes the new + errno values from the system. */ + +# ifndef ENOMSG +# define ENOMSG 2000 +# define GNULIB_defined_ENOMSG 1 +# endif + +# ifndef EIDRM +# define EIDRM 2001 +# define GNULIB_defined_EIDRM 1 +# endif + +# ifndef ENOLINK +# define ENOLINK 2002 +# define GNULIB_defined_ENOLINK 1 +# endif + +# ifndef EPROTO +# define EPROTO 2003 +# define GNULIB_defined_EPROTO 1 +# endif + +# ifndef EMULTIHOP +# define EMULTIHOP 2004 +# define GNULIB_defined_EMULTIHOP 1 +# endif + +# ifndef EBADMSG +# define EBADMSG 2005 +# define GNULIB_defined_EBADMSG 1 +# endif + +# ifndef EOVERFLOW +# define EOVERFLOW 2006 +# define GNULIB_defined_EOVERFLOW 1 +# endif + +# ifndef ENOTSUP +# define ENOTSUP 2007 +# define GNULIB_defined_ENOTSUP 1 +# endif + +# ifndef ESTALE +# define ESTALE 2009 +# define GNULIB_defined_ESTALE 1 +# endif + +# ifndef ECANCELED +# define ECANCELED 2008 +# define GNULIB_defined_ECANCELED 1 +# endif + + +#endif /* _GL_ERRNO_H */ +#endif /* _GL_ERRNO_H */ diff --git a/lib/float+.h b/lib/float+.h new file mode 100644 index 000000000..2288e3d34 --- /dev/null +++ b/lib/float+.h @@ -0,0 +1,148 @@ +/* Supplemental information about the floating-point formats. + Copyright (C) 2007 Free Software Foundation, Inc. + Written by Bruno Haible , 2007. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2, 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef _FLOATPLUS_H +#define _FLOATPLUS_H + +#include +#include + +/* Number of bits in the mantissa of a floating-point number, including the + "hidden bit". */ +#if FLT_RADIX == 2 +# define FLT_MANT_BIT FLT_MANT_DIG +# define DBL_MANT_BIT DBL_MANT_DIG +# define LDBL_MANT_BIT LDBL_MANT_DIG +#elif FLT_RADIX == 4 +# define FLT_MANT_BIT (FLT_MANT_DIG * 2) +# define DBL_MANT_BIT (DBL_MANT_DIG * 2) +# define LDBL_MANT_BIT (LDBL_MANT_DIG * 2) +#elif FLT_RADIX == 16 +# define FLT_MANT_BIT (FLT_MANT_DIG * 4) +# define DBL_MANT_BIT (DBL_MANT_DIG * 4) +# define LDBL_MANT_BIT (LDBL_MANT_DIG * 4) +#endif + +/* Bit mask that can be used to mask the exponent, as an unsigned number. */ +#define FLT_EXP_MASK ((FLT_MAX_EXP - FLT_MIN_EXP) | 7) +#define DBL_EXP_MASK ((DBL_MAX_EXP - DBL_MIN_EXP) | 7) +#define LDBL_EXP_MASK ((LDBL_MAX_EXP - LDBL_MIN_EXP) | 7) + +/* Number of bits used for the exponent of a floating-point number, including + the exponent's sign. */ +#define FLT_EXP_BIT \ + (FLT_EXP_MASK < 0x100 ? 8 : \ + FLT_EXP_MASK < 0x200 ? 9 : \ + FLT_EXP_MASK < 0x400 ? 10 : \ + FLT_EXP_MASK < 0x800 ? 11 : \ + FLT_EXP_MASK < 0x1000 ? 12 : \ + FLT_EXP_MASK < 0x2000 ? 13 : \ + FLT_EXP_MASK < 0x4000 ? 14 : \ + FLT_EXP_MASK < 0x8000 ? 15 : \ + FLT_EXP_MASK < 0x10000 ? 16 : \ + FLT_EXP_MASK < 0x20000 ? 17 : \ + FLT_EXP_MASK < 0x40000 ? 18 : \ + FLT_EXP_MASK < 0x80000 ? 19 : \ + FLT_EXP_MASK < 0x100000 ? 20 : \ + FLT_EXP_MASK < 0x200000 ? 21 : \ + FLT_EXP_MASK < 0x400000 ? 22 : \ + FLT_EXP_MASK < 0x800000 ? 23 : \ + FLT_EXP_MASK < 0x1000000 ? 24 : \ + FLT_EXP_MASK < 0x2000000 ? 25 : \ + FLT_EXP_MASK < 0x4000000 ? 26 : \ + FLT_EXP_MASK < 0x8000000 ? 27 : \ + FLT_EXP_MASK < 0x10000000 ? 28 : \ + FLT_EXP_MASK < 0x20000000 ? 29 : \ + FLT_EXP_MASK < 0x40000000 ? 30 : \ + FLT_EXP_MASK <= 0x7fffffff ? 31 : \ + 32) +#define DBL_EXP_BIT \ + (DBL_EXP_MASK < 0x100 ? 8 : \ + DBL_EXP_MASK < 0x200 ? 9 : \ + DBL_EXP_MASK < 0x400 ? 10 : \ + DBL_EXP_MASK < 0x800 ? 11 : \ + DBL_EXP_MASK < 0x1000 ? 12 : \ + DBL_EXP_MASK < 0x2000 ? 13 : \ + DBL_EXP_MASK < 0x4000 ? 14 : \ + DBL_EXP_MASK < 0x8000 ? 15 : \ + DBL_EXP_MASK < 0x10000 ? 16 : \ + DBL_EXP_MASK < 0x20000 ? 17 : \ + DBL_EXP_MASK < 0x40000 ? 18 : \ + DBL_EXP_MASK < 0x80000 ? 19 : \ + DBL_EXP_MASK < 0x100000 ? 20 : \ + DBL_EXP_MASK < 0x200000 ? 21 : \ + DBL_EXP_MASK < 0x400000 ? 22 : \ + DBL_EXP_MASK < 0x800000 ? 23 : \ + DBL_EXP_MASK < 0x1000000 ? 24 : \ + DBL_EXP_MASK < 0x2000000 ? 25 : \ + DBL_EXP_MASK < 0x4000000 ? 26 : \ + DBL_EXP_MASK < 0x8000000 ? 27 : \ + DBL_EXP_MASK < 0x10000000 ? 28 : \ + DBL_EXP_MASK < 0x20000000 ? 29 : \ + DBL_EXP_MASK < 0x40000000 ? 30 : \ + DBL_EXP_MASK <= 0x7fffffff ? 31 : \ + 32) +#define LDBL_EXP_BIT \ + (LDBL_EXP_MASK < 0x100 ? 8 : \ + LDBL_EXP_MASK < 0x200 ? 9 : \ + LDBL_EXP_MASK < 0x400 ? 10 : \ + LDBL_EXP_MASK < 0x800 ? 11 : \ + LDBL_EXP_MASK < 0x1000 ? 12 : \ + LDBL_EXP_MASK < 0x2000 ? 13 : \ + LDBL_EXP_MASK < 0x4000 ? 14 : \ + LDBL_EXP_MASK < 0x8000 ? 15 : \ + LDBL_EXP_MASK < 0x10000 ? 16 : \ + LDBL_EXP_MASK < 0x20000 ? 17 : \ + LDBL_EXP_MASK < 0x40000 ? 18 : \ + LDBL_EXP_MASK < 0x80000 ? 19 : \ + LDBL_EXP_MASK < 0x100000 ? 20 : \ + LDBL_EXP_MASK < 0x200000 ? 21 : \ + LDBL_EXP_MASK < 0x400000 ? 22 : \ + LDBL_EXP_MASK < 0x800000 ? 23 : \ + LDBL_EXP_MASK < 0x1000000 ? 24 : \ + LDBL_EXP_MASK < 0x2000000 ? 25 : \ + LDBL_EXP_MASK < 0x4000000 ? 26 : \ + LDBL_EXP_MASK < 0x8000000 ? 27 : \ + LDBL_EXP_MASK < 0x10000000 ? 28 : \ + LDBL_EXP_MASK < 0x20000000 ? 29 : \ + LDBL_EXP_MASK < 0x40000000 ? 30 : \ + LDBL_EXP_MASK <= 0x7fffffff ? 31 : \ + 32) + +/* Number of bits used for a floating-point number: the mantissa (not + counting the "hidden bit", since it may or may not be explicit), the + exponent, and the sign. */ +#define FLT_TOTAL_BIT ((FLT_MANT_BIT - 1) + FLT_EXP_BIT + 1) +#define DBL_TOTAL_BIT ((DBL_MANT_BIT - 1) + DBL_EXP_BIT + 1) +#define LDBL_TOTAL_BIT ((LDBL_MANT_BIT - 1) + LDBL_EXP_BIT + 1) + +/* Number of bytes used for a floating-point number. + This can be smaller than the 'sizeof'. For example, on i386 systems, + 'long double' most often have LDBL_MANT_BIT = 64, LDBL_EXP_BIT = 16, hence + LDBL_TOTAL_BIT = 80 bits, i.e. 10 bytes of consecutive memory, but + sizeof (long double) = 12 or = 16. */ +#define SIZEOF_FLT ((FLT_TOTAL_BIT + CHAR_BIT - 1) / CHAR_BIT) +#define SIZEOF_DBL ((DBL_TOTAL_BIT + CHAR_BIT - 1) / CHAR_BIT) +#define SIZEOF_LDBL ((LDBL_TOTAL_BIT + CHAR_BIT - 1) / CHAR_BIT) + +/* Verify that SIZEOF_FLT <= sizeof (float) etc. */ +typedef int verify_sizeof_flt[2 * (SIZEOF_FLT <= sizeof (float)) - 1]; +typedef int verify_sizeof_dbl[2 * (SIZEOF_DBL <= sizeof (double)) - 1]; +typedef int verify_sizeof_ldbl[2 * (SIZEOF_LDBL <= sizeof (long double)) - 1]; + +#endif /* _FLOATPLUS_H */ diff --git a/lib/float.in.h b/lib/float.in.h new file mode 100644 index 000000000..63d55f879 --- /dev/null +++ b/lib/float.in.h @@ -0,0 +1,62 @@ +/* A correct . + + Copyright (C) 2007-2008 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#ifndef _GL_FLOAT_H + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif + +/* The include_next requires a split double-inclusion guard. */ +#@INCLUDE_NEXT@ @NEXT_FLOAT_H@ + +#ifndef _GL_FLOAT_H +#define _GL_FLOAT_H + +/* 'long double' properties. */ +#if defined __i386__ && (defined __BEOS__ || defined __OpenBSD__) +/* Number of mantissa units, in base FLT_RADIX. */ +# undef LDBL_MANT_DIG +# define LDBL_MANT_DIG 64 +/* Number of decimal digits that is sufficient for representing a number. */ +# undef LDBL_DIG +# define LDBL_DIG 18 +/* x-1 where x is the smallest representable number > 1. */ +# undef LDBL_EPSILON +# define LDBL_EPSILON 1.0842021724855044340E-19L +/* Minimum e such that FLT_RADIX^(e-1) is a normalized number. */ +# undef LDBL_MIN_EXP +# define LDBL_MIN_EXP (-16381) +/* Maximum e such that FLT_RADIX^(e-1) is a representable finite number. */ +# undef LDBL_MAX_EXP +# define LDBL_MAX_EXP 16384 +/* Minimum positive normalized number. */ +# undef LDBL_MIN +# define LDBL_MIN 3.3621031431120935063E-4932L +/* Maximum representable finite number. */ +# undef LDBL_MAX +# define LDBL_MAX 1.1897314953572317650E+4932L +/* Minimum e such that 10^e is in the range of normalized numbers. */ +# undef LDBL_MIN_10_EXP +# define LDBL_MIN_10_EXP (-4931) +/* Maximum e such that 10^e is in the range of representable finite numbers. */ +# undef LDBL_MAX_10_EXP +# define LDBL_MAX_10_EXP 4932 +#endif + +#endif /* _GL_FLOAT_H */ +#endif /* _GL_FLOAT_H */ diff --git a/lib/flock.c b/lib/flock.c new file mode 100644 index 000000000..2993432de --- /dev/null +++ b/lib/flock.c @@ -0,0 +1,222 @@ +/* Emulate flock on platforms that lack it, primarily Windows and MinGW. + + This is derived from sqlite3 sources. + http://www.sqlite.org/cvstrac/rlog?f=sqlite/src/os_win.c + http://www.sqlite.org/copyright.html + + Written by Richard W.M. Jones + + Copyright (C) 2008 Free Software Foundation, Inc. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#include +#include + +#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ + +/* _get_osfhandle */ +#include + +/* LockFileEx */ +#define WIN32_LEAN_AND_MEAN +#include + +#include + +/* Determine the current size of a file. Because the other braindead + * APIs we'll call need lower/upper 32 bit pairs, keep the file size + * like that too. + */ +static BOOL +file_size (HANDLE h, DWORD * lower, DWORD * upper) +{ + *lower = GetFileSize (h, upper); + return 1; +} + +/* LOCKFILE_FAIL_IMMEDIATELY is undefined on some Windows systems. */ +#ifndef LOCKFILE_FAIL_IMMEDIATELY +# define LOCKFILE_FAIL_IMMEDIATELY 1 +#endif + +/* Acquire a lock. */ +static BOOL +do_lock (HANDLE h, int non_blocking, int exclusive) +{ + BOOL res; + DWORD size_lower, size_upper; + OVERLAPPED ovlp; + int flags = 0; + + /* We're going to lock the whole file, so get the file size. */ + res = file_size (h, &size_lower, &size_upper); + if (!res) + return 0; + + /* Start offset is 0, and also zero the remaining members of this struct. */ + memset (&ovlp, 0, sizeof ovlp); + + if (non_blocking) + flags |= LOCKFILE_FAIL_IMMEDIATELY; + if (exclusive) + flags |= LOCKFILE_EXCLUSIVE_LOCK; + + return LockFileEx (h, flags, 0, size_lower, size_upper, &ovlp); +} + +/* Unlock reader or exclusive lock. */ +static BOOL +do_unlock (HANDLE h) +{ + int res; + DWORD size_lower, size_upper; + + res = file_size (h, &size_lower, &size_upper); + if (!res) + return 0; + + return UnlockFile (h, 0, 0, size_lower, size_upper); +} + +/* Now our BSD-like flock operation. */ +int +flock (int fd, int operation) +{ + HANDLE h = (HANDLE) _get_osfhandle (fd); + DWORD res; + int non_blocking; + + if (h == INVALID_HANDLE_VALUE) + { + errno = EBADF; + return -1; + } + + non_blocking = operation & LOCK_NB; + operation &= ~LOCK_NB; + + switch (operation) + { + case LOCK_SH: + res = do_lock (h, non_blocking, 0); + break; + case LOCK_EX: + res = do_lock (h, non_blocking, 1); + break; + case LOCK_UN: + res = do_unlock (h); + break; + default: + errno = EINVAL; + return -1; + } + + /* Map Windows errors into Unix errnos. As usual MSDN fails to + * document the permissible error codes. + */ + if (!res) + { + DWORD err = GetLastError (); + switch (err) + { + /* This means someone else is holding a lock. */ + case ERROR_LOCK_VIOLATION: + errno = EAGAIN; + break; + + /* Out of memory. */ + case ERROR_NOT_ENOUGH_MEMORY: + errno = ENOMEM; + break; + + case ERROR_BAD_COMMAND: + errno = EINVAL; + break; + + /* Unlikely to be other errors, but at least don't lose the + * error code. + */ + default: + errno = err; + } + + return -1; + } + + return 0; +} + +#else /* !Windows */ + +#ifdef HAVE_STRUCT_FLOCK_L_TYPE +/* We know how to implement flock in terms of fcntl. */ + +#ifdef HAVE_FCNTL_H +#include +#endif + +#ifdef HAVE_UNISTD_H +#include +#endif + +#include +#include + +int +flock (int fd, int operation) +{ + int cmd, r; + struct flock fl; + + if (operation & LOCK_NB) + cmd = F_SETLK; + else + cmd = F_SETLKW; + operation &= ~LOCK_NB; + + memset (&fl, 0, sizeof fl); + fl.l_whence = SEEK_SET; + /* l_start & l_len are 0, which as a special case means "whole file". */ + + switch (operation) + { + case LOCK_SH: + fl.l_type = F_RDLCK; + break; + case LOCK_EX: + fl.l_type = F_WRLCK; + break; + case LOCK_UN: + fl.l_type = F_UNLCK; + break; + default: + errno = EINVAL; + return -1; + } + + r = fcntl (fd, cmd, &fl); + if (r == -1 && errno == EACCES) + errno = EAGAIN; + + return r; +} + +#else /* !HAVE_STRUCT_FLOCK_L_TYPE */ + +#error "This platform lacks flock function, and Gnulib doesn't provide a replacement. This is a bug in Gnulib." + +#endif /* !HAVE_STRUCT_FLOCK_L_TYPE */ + +#endif /* !Windows */ diff --git a/lib/getpagesize.c b/lib/getpagesize.c new file mode 100644 index 000000000..82238df19 --- /dev/null +++ b/lib/getpagesize.c @@ -0,0 +1,39 @@ +/* getpagesize emulation for systems where it cannot be done in a C macro. + + Copyright (C) 2007 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +/* Written by Bruno Haible and Martin Lambers. */ + +#include + +/* Specification. */ +#include + +/* This implementation is only for native Win32 systems. */ +#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ + +# define WIN32_LEAN_AND_MEAN +# include + +int +getpagesize (void) +{ + SYSTEM_INFO system_info; + GetSystemInfo (&system_info); + return system_info.dwPageSize; +} + +#endif diff --git a/lib/iconv.c b/lib/iconv.c new file mode 100644 index 000000000..56a84c456 --- /dev/null +++ b/lib/iconv.c @@ -0,0 +1,450 @@ +/* Character set conversion. + Copyright (C) 1999-2001, 2007 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2, 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License along + with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include + +/* Specification. */ +#include + +#include + +#if REPLACE_ICONV_UTF +# include +# include +# include +# include "unistr.h" +# ifndef uintptr_t +# define uintptr_t unsigned long +# endif +#endif + +#if REPLACE_ICONV_UTF + +/* UTF-{16,32}{BE,LE} converters taken from GNU libiconv 1.11. */ + +/* Return code if invalid. (xxx_mbtowc) */ +# define RET_ILSEQ -1 +/* Return code if no bytes were read. (xxx_mbtowc) */ +# define RET_TOOFEW -2 + +/* Return code if invalid. (xxx_wctomb) */ +# define RET_ILUNI -1 +/* Return code if output buffer is too small. (xxx_wctomb, xxx_reset) */ +# define RET_TOOSMALL -2 + +/* + * UTF-16BE + */ + +/* Specification: RFC 2781 */ + +static int +utf16be_mbtowc (ucs4_t *pwc, const unsigned char *s, size_t n) +{ + if (n >= 2) + { + ucs4_t wc = (s[0] << 8) + s[1]; + if (wc >= 0xd800 && wc < 0xdc00) + { + if (n >= 4) + { + ucs4_t wc2 = (s[2] << 8) + s[3]; + if (!(wc2 >= 0xdc00 && wc2 < 0xe000)) + return RET_ILSEQ; + *pwc = 0x10000 + ((wc - 0xd800) << 10) + (wc2 - 0xdc00); + return 4; + } + } + else if (wc >= 0xdc00 && wc < 0xe000) + { + return RET_ILSEQ; + } + else + { + *pwc = wc; + return 2; + } + } + return RET_TOOFEW; +} + +static int +utf16be_wctomb (unsigned char *r, ucs4_t wc, size_t n) +{ + if (!(wc >= 0xd800 && wc < 0xe000)) + { + if (wc < 0x10000) + { + if (n >= 2) + { + r[0] = (unsigned char) (wc >> 8); + r[1] = (unsigned char) wc; + return 2; + } + else + return RET_TOOSMALL; + } + else if (wc < 0x110000) + { + if (n >= 4) + { + ucs4_t wc1 = 0xd800 + ((wc - 0x10000) >> 10); + ucs4_t wc2 = 0xdc00 + ((wc - 0x10000) & 0x3ff); + r[0] = (unsigned char) (wc1 >> 8); + r[1] = (unsigned char) wc1; + r[2] = (unsigned char) (wc2 >> 8); + r[3] = (unsigned char) wc2; + return 4; + } + else + return RET_TOOSMALL; + } + } + return RET_ILUNI; +} + +/* + * UTF-16LE + */ + +/* Specification: RFC 2781 */ + +static int +utf16le_mbtowc (ucs4_t *pwc, const unsigned char *s, size_t n) +{ + if (n >= 2) + { + ucs4_t wc = s[0] + (s[1] << 8); + if (wc >= 0xd800 && wc < 0xdc00) + { + if (n >= 4) + { + ucs4_t wc2 = s[2] + (s[3] << 8); + if (!(wc2 >= 0xdc00 && wc2 < 0xe000)) + return RET_ILSEQ; + *pwc = 0x10000 + ((wc - 0xd800) << 10) + (wc2 - 0xdc00); + return 4; + } + } + else if (wc >= 0xdc00 && wc < 0xe000) + { + return RET_ILSEQ; + } + else + { + *pwc = wc; + return 2; + } + } + return RET_TOOFEW; +} + +static int +utf16le_wctomb (unsigned char *r, ucs4_t wc, size_t n) +{ + if (!(wc >= 0xd800 && wc < 0xe000)) + { + if (wc < 0x10000) + { + if (n >= 2) + { + r[0] = (unsigned char) wc; + r[1] = (unsigned char) (wc >> 8); + return 2; + } + else + return RET_TOOSMALL; + } + else if (wc < 0x110000) + { + if (n >= 4) + { + ucs4_t wc1 = 0xd800 + ((wc - 0x10000) >> 10); + ucs4_t wc2 = 0xdc00 + ((wc - 0x10000) & 0x3ff); + r[0] = (unsigned char) wc1; + r[1] = (unsigned char) (wc1 >> 8); + r[2] = (unsigned char) wc2; + r[3] = (unsigned char) (wc2 >> 8); + return 4; + } + else + return RET_TOOSMALL; + } + } + return RET_ILUNI; +} + +/* + * UTF-32BE + */ + +/* Specification: Unicode 3.1 Standard Annex #19 */ + +static int +utf32be_mbtowc (ucs4_t *pwc, const unsigned char *s, size_t n) +{ + if (n >= 4) + { + ucs4_t wc = (s[0] << 24) + (s[1] << 16) + (s[2] << 8) + s[3]; + if (wc < 0x110000 && !(wc >= 0xd800 && wc < 0xe000)) + { + *pwc = wc; + return 4; + } + else + return RET_ILSEQ; + } + return RET_TOOFEW; +} + +static int +utf32be_wctomb (unsigned char *r, ucs4_t wc, size_t n) +{ + if (wc < 0x110000 && !(wc >= 0xd800 && wc < 0xe000)) + { + if (n >= 4) + { + r[0] = 0; + r[1] = (unsigned char) (wc >> 16); + r[2] = (unsigned char) (wc >> 8); + r[3] = (unsigned char) wc; + return 4; + } + else + return RET_TOOSMALL; + } + return RET_ILUNI; +} + +/* + * UTF-32LE + */ + +/* Specification: Unicode 3.1 Standard Annex #19 */ + +static int +utf32le_mbtowc (ucs4_t *pwc, const unsigned char *s, size_t n) +{ + if (n >= 4) + { + ucs4_t wc = s[0] + (s[1] << 8) + (s[2] << 16) + (s[3] << 24); + if (wc < 0x110000 && !(wc >= 0xd800 && wc < 0xe000)) + { + *pwc = wc; + return 4; + } + else + return RET_ILSEQ; + } + return RET_TOOFEW; +} + +static int +utf32le_wctomb (unsigned char *r, ucs4_t wc, size_t n) +{ + if (wc < 0x110000 && !(wc >= 0xd800 && wc < 0xe000)) + { + if (n >= 4) + { + r[0] = (unsigned char) wc; + r[1] = (unsigned char) (wc >> 8); + r[2] = (unsigned char) (wc >> 16); + r[3] = 0; + return 4; + } + else + return RET_TOOSMALL; + } + return RET_ILUNI; +} + +#endif + +size_t +rpl_iconv (iconv_t cd, + ICONV_CONST char **inbuf, size_t *inbytesleft, + char **outbuf, size_t *outbytesleft) +#undef iconv +{ +#if REPLACE_ICONV_UTF + switch ((uintptr_t) cd) + { + { + int (*xxx_wctomb) (unsigned char *, ucs4_t, size_t); + + case (uintptr_t) _ICONV_UTF8_UTF16BE: + xxx_wctomb = utf16be_wctomb; + goto loop_from_utf8; + case (uintptr_t) _ICONV_UTF8_UTF16LE: + xxx_wctomb = utf16le_wctomb; + goto loop_from_utf8; + case (uintptr_t) _ICONV_UTF8_UTF32BE: + xxx_wctomb = utf32be_wctomb; + goto loop_from_utf8; + case (uintptr_t) _ICONV_UTF8_UTF32LE: + xxx_wctomb = utf32le_wctomb; + goto loop_from_utf8; + + loop_from_utf8: + if (inbuf == NULL || *inbuf == NULL) + return 0; + { + ICONV_CONST char *inptr = *inbuf; + size_t inleft = *inbytesleft; + char *outptr = *outbuf; + size_t outleft = *outbytesleft; + size_t res = 0; + while (inleft > 0) + { + ucs4_t uc; + int m = u8_mbtoucr (&uc, (const uint8_t *) inptr, inleft); + if (m <= 0) + { + if (m == -1) + { + errno = EILSEQ; + res = (size_t)(-1); + break; + } + if (m == -2) + { + errno = EINVAL; + res = (size_t)(-1); + break; + } + abort (); + } + else + { + int n = xxx_wctomb ((uint8_t *) outptr, uc, outleft); + if (n < 0) + { + if (n == RET_ILUNI) + { + errno = EILSEQ; + res = (size_t)(-1); + break; + } + if (n == RET_TOOSMALL) + { + errno = E2BIG; + res = (size_t)(-1); + break; + } + abort (); + } + else + { + inptr += m; + inleft -= m; + outptr += n; + outleft -= n; + } + } + } + *inbuf = inptr; + *inbytesleft = inleft; + *outbuf = outptr; + *outbytesleft = outleft; + return res; + } + } + + { + int (*xxx_mbtowc) (ucs4_t *, const unsigned char *, size_t); + + case (uintptr_t) _ICONV_UTF16BE_UTF8: + xxx_mbtowc = utf16be_mbtowc; + goto loop_to_utf8; + case (uintptr_t) _ICONV_UTF16LE_UTF8: + xxx_mbtowc = utf16le_mbtowc; + goto loop_to_utf8; + case (uintptr_t) _ICONV_UTF32BE_UTF8: + xxx_mbtowc = utf32be_mbtowc; + goto loop_to_utf8; + case (uintptr_t) _ICONV_UTF32LE_UTF8: + xxx_mbtowc = utf32le_mbtowc; + goto loop_to_utf8; + + loop_to_utf8: + if (inbuf == NULL || *inbuf == NULL) + return 0; + { + ICONV_CONST char *inptr = *inbuf; + size_t inleft = *inbytesleft; + char *outptr = *outbuf; + size_t outleft = *outbytesleft; + size_t res = 0; + while (inleft > 0) + { + ucs4_t uc; + int m = xxx_mbtowc (&uc, (const uint8_t *) inptr, inleft); + if (m <= 0) + { + if (m == RET_ILSEQ) + { + errno = EILSEQ; + res = (size_t)(-1); + break; + } + if (m == RET_TOOFEW) + { + errno = EINVAL; + res = (size_t)(-1); + break; + } + abort (); + } + else + { + int n = u8_uctomb ((uint8_t *) outptr, uc, outleft); + if (n < 0) + { + if (n == -1) + { + errno = EILSEQ; + res = (size_t)(-1); + break; + } + if (n == -2) + { + errno = E2BIG; + res = (size_t)(-1); + break; + } + abort (); + } + else + { + inptr += m; + inleft -= m; + outptr += n; + outleft -= n; + } + } + } + *inbuf = inptr; + *inbytesleft = inleft; + *outbuf = outptr; + *outbytesleft = outleft; + return res; + } + } + } +#endif + return iconv (cd, inbuf, inbytesleft, outbuf, outbytesleft); +} diff --git a/lib/iconv.in.h b/lib/iconv.in.h new file mode 100644 index 000000000..915dce2e7 --- /dev/null +++ b/lib/iconv.in.h @@ -0,0 +1,71 @@ +/* A GNU-like . + + Copyright (C) 2007-2008 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2, 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef _GL_ICONV_H + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif + +/* The include_next requires a split double-inclusion guard. */ +#@INCLUDE_NEXT@ @NEXT_ICONV_H@ + +#ifndef _GL_ICONV_H +#define _GL_ICONV_H + +#ifdef __cplusplus +extern "C" { +#endif + + +#if @REPLACE_ICONV_OPEN@ +/* An iconv_open wrapper that supports the IANA standardized encoding names + ("ISO-8859-1" etc.) as far as possible. */ +# define iconv_open rpl_iconv_open +extern iconv_t iconv_open (const char *tocode, const char *fromcode); +#endif + +#if @REPLACE_ICONV_UTF@ +/* Special constants for supporting UTF-{16,32}{BE,LE} encodings. + Not public. */ +# define _ICONV_UTF8_UTF16BE (iconv_t)(-161) +# define _ICONV_UTF8_UTF16LE (iconv_t)(-162) +# define _ICONV_UTF8_UTF32BE (iconv_t)(-163) +# define _ICONV_UTF8_UTF32LE (iconv_t)(-164) +# define _ICONV_UTF16BE_UTF8 (iconv_t)(-165) +# define _ICONV_UTF16LE_UTF8 (iconv_t)(-166) +# define _ICONV_UTF32BE_UTF8 (iconv_t)(-167) +# define _ICONV_UTF32LE_UTF8 (iconv_t)(-168) +#endif + +#if @REPLACE_ICONV@ +# define iconv rpl_iconv +extern size_t iconv (iconv_t cd, + @ICONV_CONST@ char **inbuf, size_t *inbytesleft, + char **outbuf, size_t *outbytesleft); +# define iconv_close rpl_iconv_close +extern int iconv_close (iconv_t cd); +#endif + + +#ifdef __cplusplus +} +#endif + +#endif /* _GL_ICONV_H */ +#endif /* _GL_ICONV_H */ diff --git a/lib/iconv_close.c b/lib/iconv_close.c new file mode 100644 index 000000000..3680412a0 --- /dev/null +++ b/lib/iconv_close.c @@ -0,0 +1,47 @@ +/* Character set conversion. + Copyright (C) 2007 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2, 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License along + with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include + +/* Specification. */ +#include + +#include +#ifndef uintptr_t +# define uintptr_t unsigned long +#endif + +int +rpl_iconv_close (iconv_t cd) +#undef iconv_close +{ +#if REPLACE_ICONV_UTF + switch ((uintptr_t) cd) + { + case (uintptr_t) _ICONV_UTF8_UTF16BE: + case (uintptr_t) _ICONV_UTF8_UTF16LE: + case (uintptr_t) _ICONV_UTF8_UTF32BE: + case (uintptr_t) _ICONV_UTF8_UTF32LE: + case (uintptr_t) _ICONV_UTF16BE_UTF8: + case (uintptr_t) _ICONV_UTF16LE_UTF8: + case (uintptr_t) _ICONV_UTF32BE_UTF8: + case (uintptr_t) _ICONV_UTF32LE_UTF8: + return 0; + } +#endif + return iconv_close (cd); +} diff --git a/lib/iconv_open-aix.gperf b/lib/iconv_open-aix.gperf new file mode 100644 index 000000000..6782b9956 --- /dev/null +++ b/lib/iconv_open-aix.gperf @@ -0,0 +1,44 @@ +struct mapping { int standard_name; const char vendor_name[10 + 1]; }; +%struct-type +%language=ANSI-C +%define slot-name standard_name +%define hash-function-name mapping_hash +%define lookup-function-name mapping_lookup +%readonly-tables +%global-table +%define word-array-name mappings +%pic +%% +# On AIX 5.1, look in /usr/lib/nls/loc/uconvTable. +ISO-8859-1, "ISO8859-1" +ISO-8859-2, "ISO8859-2" +ISO-8859-3, "ISO8859-3" +ISO-8859-4, "ISO8859-4" +ISO-8859-5, "ISO8859-5" +ISO-8859-6, "ISO8859-6" +ISO-8859-7, "ISO8859-7" +ISO-8859-8, "ISO8859-8" +ISO-8859-9, "ISO8859-9" +ISO-8859-15, "ISO8859-15" +CP437, "IBM-437" +CP850, "IBM-850" +CP852, "IBM-852" +CP856, "IBM-856" +CP857, "IBM-857" +CP861, "IBM-861" +CP865, "IBM-865" +CP869, "IBM-869" +ISO-8859-13, "IBM-921" +CP922, "IBM-922" +CP932, "IBM-932" +CP943, "IBM-943" +CP1046, "IBM-1046" +CP1124, "IBM-1124" +CP1125, "IBM-1125" +CP1129, "IBM-1129" +CP1252, "IBM-1252" +GB2312, "IBM-eucCN" +EUC-JP, "IBM-eucJP" +EUC-KR, "IBM-eucKR" +EUC-TW, "IBM-eucTW" +BIG5, "big5" diff --git a/lib/iconv_open-aix.h b/lib/iconv_open-aix.h new file mode 100644 index 000000000..0ffc3fef1 --- /dev/null +++ b/lib/iconv_open-aix.h @@ -0,0 +1,256 @@ +/* ANSI-C code produced by gperf version 3.0.3 */ +/* Command-line: gperf -m 10 ./iconv_open-aix.gperf */ +/* Computed positions: -k'4,$' */ + +#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ + && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ + && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ + && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ + && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ + && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ + && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ + && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ + && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ + && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ + && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ + && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ + && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ + && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ + && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ + && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ + && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ + && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ + && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ + && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ + && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ + && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ + && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) +/* The character set is not based on ISO-646. */ +#error "gperf generated tables don't work with this execution character set. Please report a bug to ." +#endif + +#line 1 "./iconv_open-aix.gperf" +struct mapping { int standard_name; const char vendor_name[10 + 1]; }; + +#define TOTAL_KEYWORDS 32 +#define MIN_WORD_LENGTH 4 +#define MAX_WORD_LENGTH 11 +#define MIN_HASH_VALUE 6 +#define MAX_HASH_VALUE 44 +/* maximum key range = 39, duplicates = 0 */ + +#ifdef __GNUC__ +__inline +#else +#ifdef __cplusplus +inline +#endif +#endif +static unsigned int +mapping_hash (register const char *str, register unsigned int len) +{ + static const unsigned char asso_values[] = + { + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 0, 4, 25, + 0, 11, 24, 9, 17, 3, 14, 21, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 3, 45, 1, 45, 45, 45, 45, 0, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45 + }; + return len + asso_values[(unsigned char)str[3]+2] + asso_values[(unsigned char)str[len - 1]]; +} + +struct stringpool_t + { + char stringpool_str6[sizeof("EUC-TW")]; + char stringpool_str7[sizeof("EUC-KR")]; + char stringpool_str8[sizeof("CP852")]; + char stringpool_str9[sizeof("EUC-JP")]; + char stringpool_str10[sizeof("ISO-8859-2")]; + char stringpool_str11[sizeof("CP857")]; + char stringpool_str12[sizeof("CP850")]; + char stringpool_str13[sizeof("ISO-8859-7")]; + char stringpool_str14[sizeof("CP932")]; + char stringpool_str15[sizeof("GB2312")]; + char stringpool_str16[sizeof("BIG5")]; + char stringpool_str17[sizeof("CP437")]; + char stringpool_str19[sizeof("ISO-8859-5")]; + char stringpool_str20[sizeof("ISO-8859-15")]; + char stringpool_str21[sizeof("ISO-8859-3")]; + char stringpool_str22[sizeof("ISO-8859-13")]; + char stringpool_str23[sizeof("CP1046")]; + char stringpool_str24[sizeof("ISO-8859-8")]; + char stringpool_str25[sizeof("CP856")]; + char stringpool_str26[sizeof("CP1125")]; + char stringpool_str27[sizeof("ISO-8859-6")]; + char stringpool_str28[sizeof("CP865")]; + char stringpool_str29[sizeof("CP922")]; + char stringpool_str30[sizeof("CP1252")]; + char stringpool_str31[sizeof("ISO-8859-9")]; + char stringpool_str33[sizeof("CP943")]; + char stringpool_str34[sizeof("ISO-8859-4")]; + char stringpool_str35[sizeof("ISO-8859-1")]; + char stringpool_str38[sizeof("CP1129")]; + char stringpool_str40[sizeof("CP869")]; + char stringpool_str41[sizeof("CP1124")]; + char stringpool_str44[sizeof("CP861")]; + }; +static const struct stringpool_t stringpool_contents = + { + "EUC-TW", + "EUC-KR", + "CP852", + "EUC-JP", + "ISO-8859-2", + "CP857", + "CP850", + "ISO-8859-7", + "CP932", + "GB2312", + "BIG5", + "CP437", + "ISO-8859-5", + "ISO-8859-15", + "ISO-8859-3", + "ISO-8859-13", + "CP1046", + "ISO-8859-8", + "CP856", + "CP1125", + "ISO-8859-6", + "CP865", + "CP922", + "CP1252", + "ISO-8859-9", + "CP943", + "ISO-8859-4", + "ISO-8859-1", + "CP1129", + "CP869", + "CP1124", + "CP861" + }; +#define stringpool ((const char *) &stringpool_contents) + +static const struct mapping mappings[] = + { + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 43 "./iconv_open-aix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str6, "IBM-eucTW"}, +#line 42 "./iconv_open-aix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str7, "IBM-eucKR"}, +#line 25 "./iconv_open-aix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str8, "IBM-852"}, +#line 41 "./iconv_open-aix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str9, "IBM-eucJP"}, +#line 14 "./iconv_open-aix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str10, "ISO8859-2"}, +#line 27 "./iconv_open-aix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str11, "IBM-857"}, +#line 24 "./iconv_open-aix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str12, "IBM-850"}, +#line 19 "./iconv_open-aix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str13, "ISO8859-7"}, +#line 33 "./iconv_open-aix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str14, "IBM-932"}, +#line 40 "./iconv_open-aix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str15, "IBM-eucCN"}, +#line 44 "./iconv_open-aix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str16, "big5"}, +#line 23 "./iconv_open-aix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str17, "IBM-437"}, + {-1}, +#line 17 "./iconv_open-aix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str19, "ISO8859-5"}, +#line 22 "./iconv_open-aix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str20, "ISO8859-15"}, +#line 15 "./iconv_open-aix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str21, "ISO8859-3"}, +#line 31 "./iconv_open-aix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str22, "IBM-921"}, +#line 35 "./iconv_open-aix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str23, "IBM-1046"}, +#line 20 "./iconv_open-aix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str24, "ISO8859-8"}, +#line 26 "./iconv_open-aix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str25, "IBM-856"}, +#line 37 "./iconv_open-aix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str26, "IBM-1125"}, +#line 18 "./iconv_open-aix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str27, "ISO8859-6"}, +#line 29 "./iconv_open-aix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str28, "IBM-865"}, +#line 32 "./iconv_open-aix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str29, "IBM-922"}, +#line 39 "./iconv_open-aix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str30, "IBM-1252"}, +#line 21 "./iconv_open-aix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str31, "ISO8859-9"}, + {-1}, +#line 34 "./iconv_open-aix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str33, "IBM-943"}, +#line 16 "./iconv_open-aix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str34, "ISO8859-4"}, +#line 13 "./iconv_open-aix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str35, "ISO8859-1"}, + {-1}, {-1}, +#line 38 "./iconv_open-aix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str38, "IBM-1129"}, + {-1}, +#line 30 "./iconv_open-aix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str40, "IBM-869"}, +#line 36 "./iconv_open-aix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str41, "IBM-1124"}, + {-1}, {-1}, +#line 28 "./iconv_open-aix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str44, "IBM-861"} + }; + +#ifdef __GNUC__ +__inline +#ifdef __GNUC_STDC_INLINE__ +__attribute__ ((__gnu_inline__)) +#endif +#endif +const struct mapping * +mapping_lookup (register const char *str, register unsigned int len) +{ + if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) + { + register int key = mapping_hash (str, len); + + if (key <= MAX_HASH_VALUE && key >= 0) + { + register int o = mappings[key].standard_name; + if (o >= 0) + { + register const char *s = o + stringpool; + + if (*str == *s && !strcmp (str + 1, s + 1)) + return &mappings[key]; + } + } + } + return 0; +} diff --git a/lib/iconv_open-hpux.gperf b/lib/iconv_open-hpux.gperf new file mode 100644 index 000000000..5a35c83e1 --- /dev/null +++ b/lib/iconv_open-hpux.gperf @@ -0,0 +1,56 @@ +struct mapping { int standard_name; const char vendor_name[9 + 1]; }; +%struct-type +%language=ANSI-C +%define slot-name standard_name +%define hash-function-name mapping_hash +%define lookup-function-name mapping_lookup +%readonly-tables +%global-table +%define word-array-name mappings +%pic +%% +# On HP-UX 11.11, look in /usr/lib/nls/iconv. +ISO-8859-1, "iso88591" +ISO-8859-2, "iso88592" +ISO-8859-5, "iso88595" +ISO-8859-6, "iso88596" +ISO-8859-7, "iso88597" +ISO-8859-8, "iso88598" +ISO-8859-9, "iso88599" +ISO-8859-15, "iso885915" +CP437, "cp437" +CP775, "cp775" +CP850, "cp850" +CP852, "cp852" +CP855, "cp855" +CP857, "cp857" +CP861, "cp861" +CP862, "cp862" +CP864, "cp864" +CP865, "cp865" +CP866, "cp866" +CP869, "cp869" +CP874, "cp874" +CP1250, "cp1250" +CP1251, "cp1251" +CP1252, "cp1252" +CP1253, "cp1253" +CP1254, "cp1254" +CP1255, "cp1255" +CP1256, "cp1256" +CP1257, "cp1257" +CP1258, "cp1258" +HP-ROMAN8, "roman8" +HP-ARABIC8, "arabic8" +HP-GREEK8, "greek8" +HP-HEBREW8, "hebrew8" +HP-TURKISH8, "turkish8" +HP-KANA8, "kana8" +TIS-620, "tis620" +GB2312, "hp15CN" +EUC-JP, "eucJP" +EUC-KR, "eucKR" +EUC-TW, "eucTW" +BIG5, "big5" +SHIFT_JIS, "sjis" +UTF-8, "utf8" diff --git a/lib/iconv_open-hpux.h b/lib/iconv_open-hpux.h new file mode 100644 index 000000000..8f9f0a9ad --- /dev/null +++ b/lib/iconv_open-hpux.h @@ -0,0 +1,299 @@ +/* ANSI-C code produced by gperf version 3.0.3 */ +/* Command-line: gperf -m 10 ./iconv_open-hpux.gperf */ +/* Computed positions: -k'4,$' */ + +#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ + && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ + && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ + && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ + && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ + && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ + && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ + && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ + && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ + && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ + && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ + && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ + && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ + && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ + && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ + && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ + && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ + && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ + && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ + && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ + && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ + && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ + && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) +/* The character set is not based on ISO-646. */ +#error "gperf generated tables don't work with this execution character set. Please report a bug to ." +#endif + +#line 1 "./iconv_open-hpux.gperf" +struct mapping { int standard_name; const char vendor_name[9 + 1]; }; + +#define TOTAL_KEYWORDS 44 +#define MIN_WORD_LENGTH 4 +#define MAX_WORD_LENGTH 11 +#define MIN_HASH_VALUE 6 +#define MAX_HASH_VALUE 49 +/* maximum key range = 44, duplicates = 0 */ + +#ifdef __GNUC__ +__inline +#else +#ifdef __cplusplus +inline +#endif +#endif +static unsigned int +mapping_hash (register const char *str, register unsigned int len) +{ + static const unsigned char asso_values[] = + { + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 1, 2, + 24, 43, 5, 10, 0, 13, 32, 3, 19, 18, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 5, + 50, 50, 50, 50, 14, 5, 0, 50, 50, 0, + 27, 50, 12, 14, 50, 50, 0, 5, 2, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50 + }; + return len + asso_values[(unsigned char)str[3]+4] + asso_values[(unsigned char)str[len - 1]]; +} + +struct stringpool_t + { + char stringpool_str6[sizeof("CP1256")]; + char stringpool_str7[sizeof("CP1250")]; + char stringpool_str8[sizeof("CP1251")]; + char stringpool_str9[sizeof("CP850")]; + char stringpool_str10[sizeof("TIS-620")]; + char stringpool_str11[sizeof("CP1254")]; + char stringpool_str12[sizeof("ISO-8859-6")]; + char stringpool_str13[sizeof("EUC-TW")]; + char stringpool_str14[sizeof("ISO-8859-1")]; + char stringpool_str15[sizeof("ISO-8859-9")]; + char stringpool_str16[sizeof("CP1255")]; + char stringpool_str17[sizeof("BIG5")]; + char stringpool_str18[sizeof("CP855")]; + char stringpool_str19[sizeof("CP1257")]; + char stringpool_str20[sizeof("EUC-KR")]; + char stringpool_str21[sizeof("CP857")]; + char stringpool_str22[sizeof("ISO-8859-5")]; + char stringpool_str23[sizeof("ISO-8859-15")]; + char stringpool_str24[sizeof("CP866")]; + char stringpool_str25[sizeof("ISO-8859-7")]; + char stringpool_str26[sizeof("CP861")]; + char stringpool_str27[sizeof("CP869")]; + char stringpool_str28[sizeof("CP874")]; + char stringpool_str29[sizeof("CP864")]; + char stringpool_str30[sizeof("CP1252")]; + char stringpool_str31[sizeof("CP437")]; + char stringpool_str32[sizeof("CP852")]; + char stringpool_str33[sizeof("CP775")]; + char stringpool_str34[sizeof("CP865")]; + char stringpool_str35[sizeof("EUC-JP")]; + char stringpool_str36[sizeof("ISO-8859-2")]; + char stringpool_str37[sizeof("SHIFT_JIS")]; + char stringpool_str38[sizeof("CP1258")]; + char stringpool_str39[sizeof("UTF-8")]; + char stringpool_str40[sizeof("HP-KANA8")]; + char stringpool_str41[sizeof("HP-ROMAN8")]; + char stringpool_str42[sizeof("HP-HEBREW8")]; + char stringpool_str43[sizeof("GB2312")]; + char stringpool_str44[sizeof("ISO-8859-8")]; + char stringpool_str45[sizeof("HP-TURKISH8")]; + char stringpool_str46[sizeof("HP-GREEK8")]; + char stringpool_str47[sizeof("HP-ARABIC8")]; + char stringpool_str48[sizeof("CP862")]; + char stringpool_str49[sizeof("CP1253")]; + }; +static const struct stringpool_t stringpool_contents = + { + "CP1256", + "CP1250", + "CP1251", + "CP850", + "TIS-620", + "CP1254", + "ISO-8859-6", + "EUC-TW", + "ISO-8859-1", + "ISO-8859-9", + "CP1255", + "BIG5", + "CP855", + "CP1257", + "EUC-KR", + "CP857", + "ISO-8859-5", + "ISO-8859-15", + "CP866", + "ISO-8859-7", + "CP861", + "CP869", + "CP874", + "CP864", + "CP1252", + "CP437", + "CP852", + "CP775", + "CP865", + "EUC-JP", + "ISO-8859-2", + "SHIFT_JIS", + "CP1258", + "UTF-8", + "HP-KANA8", + "HP-ROMAN8", + "HP-HEBREW8", + "GB2312", + "ISO-8859-8", + "HP-TURKISH8", + "HP-GREEK8", + "HP-ARABIC8", + "CP862", + "CP1253" + }; +#define stringpool ((const char *) &stringpool_contents) + +static const struct mapping mappings[] = + { + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 40 "./iconv_open-hpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str6, "cp1256"}, +#line 34 "./iconv_open-hpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str7, "cp1250"}, +#line 35 "./iconv_open-hpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str8, "cp1251"}, +#line 23 "./iconv_open-hpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str9, "cp850"}, +#line 49 "./iconv_open-hpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str10, "tis620"}, +#line 38 "./iconv_open-hpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str11, "cp1254"}, +#line 16 "./iconv_open-hpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str12, "iso88596"}, +#line 53 "./iconv_open-hpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str13, "eucTW"}, +#line 13 "./iconv_open-hpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str14, "iso88591"}, +#line 19 "./iconv_open-hpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str15, "iso88599"}, +#line 39 "./iconv_open-hpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str16, "cp1255"}, +#line 54 "./iconv_open-hpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str17, "big5"}, +#line 25 "./iconv_open-hpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str18, "cp855"}, +#line 41 "./iconv_open-hpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str19, "cp1257"}, +#line 52 "./iconv_open-hpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str20, "eucKR"}, +#line 26 "./iconv_open-hpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str21, "cp857"}, +#line 15 "./iconv_open-hpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str22, "iso88595"}, +#line 20 "./iconv_open-hpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str23, "iso885915"}, +#line 31 "./iconv_open-hpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str24, "cp866"}, +#line 17 "./iconv_open-hpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str25, "iso88597"}, +#line 27 "./iconv_open-hpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str26, "cp861"}, +#line 32 "./iconv_open-hpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str27, "cp869"}, +#line 33 "./iconv_open-hpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str28, "cp874"}, +#line 29 "./iconv_open-hpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str29, "cp864"}, +#line 36 "./iconv_open-hpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str30, "cp1252"}, +#line 21 "./iconv_open-hpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str31, "cp437"}, +#line 24 "./iconv_open-hpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str32, "cp852"}, +#line 22 "./iconv_open-hpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str33, "cp775"}, +#line 30 "./iconv_open-hpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str34, "cp865"}, +#line 51 "./iconv_open-hpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str35, "eucJP"}, +#line 14 "./iconv_open-hpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str36, "iso88592"}, +#line 55 "./iconv_open-hpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str37, "sjis"}, +#line 42 "./iconv_open-hpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str38, "cp1258"}, +#line 56 "./iconv_open-hpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str39, "utf8"}, +#line 48 "./iconv_open-hpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str40, "kana8"}, +#line 43 "./iconv_open-hpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str41, "roman8"}, +#line 46 "./iconv_open-hpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str42, "hebrew8"}, +#line 50 "./iconv_open-hpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str43, "hp15CN"}, +#line 18 "./iconv_open-hpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str44, "iso88598"}, +#line 47 "./iconv_open-hpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str45, "turkish8"}, +#line 45 "./iconv_open-hpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str46, "greek8"}, +#line 44 "./iconv_open-hpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str47, "arabic8"}, +#line 28 "./iconv_open-hpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str48, "cp862"}, +#line 37 "./iconv_open-hpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str49, "cp1253"} + }; + +#ifdef __GNUC__ +__inline +#ifdef __GNUC_STDC_INLINE__ +__attribute__ ((__gnu_inline__)) +#endif +#endif +const struct mapping * +mapping_lookup (register const char *str, register unsigned int len) +{ + if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) + { + register int key = mapping_hash (str, len); + + if (key <= MAX_HASH_VALUE && key >= 0) + { + register int o = mappings[key].standard_name; + if (o >= 0) + { + register const char *s = o + stringpool; + + if (*str == *s && !strcmp (str + 1, s + 1)) + return &mappings[key]; + } + } + } + return 0; +} diff --git a/lib/iconv_open-irix.gperf b/lib/iconv_open-irix.gperf new file mode 100644 index 000000000..3672a8013 --- /dev/null +++ b/lib/iconv_open-irix.gperf @@ -0,0 +1,31 @@ +struct mapping { int standard_name; const char vendor_name[10 + 1]; }; +%struct-type +%language=ANSI-C +%define slot-name standard_name +%define hash-function-name mapping_hash +%define lookup-function-name mapping_lookup +%readonly-tables +%global-table +%define word-array-name mappings +%pic +%% +# On IRIX 6.5, look in /usr/lib/iconv and /usr/lib/international/encodings. +ISO-8859-1, "ISO8859-1" +ISO-8859-2, "ISO8859-2" +ISO-8859-3, "ISO8859-3" +ISO-8859-4, "ISO8859-4" +ISO-8859-5, "ISO8859-5" +ISO-8859-6, "ISO8859-6" +ISO-8859-7, "ISO8859-7" +ISO-8859-8, "ISO8859-8" +ISO-8859-9, "ISO8859-9" +ISO-8859-15, "ISO8859-15" +KOI8-R, "KOI8" +CP855, "DOS855" +CP1251, "WIN1251" +GB2312, "eucCN" +EUC-JP, "eucJP" +EUC-KR, "eucKR" +EUC-TW, "eucTW" +SHIFT_JIS, "sjis" +TIS-620, "TIS620" diff --git a/lib/iconv_open-irix.h b/lib/iconv_open-irix.h new file mode 100644 index 000000000..520582e52 --- /dev/null +++ b/lib/iconv_open-irix.h @@ -0,0 +1,199 @@ +/* ANSI-C code produced by gperf version 3.0.3 */ +/* Command-line: gperf -m 10 ./iconv_open-irix.gperf */ +/* Computed positions: -k'1,$' */ + +#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ + && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ + && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ + && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ + && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ + && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ + && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ + && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ + && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ + && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ + && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ + && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ + && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ + && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ + && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ + && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ + && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ + && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ + && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ + && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ + && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ + && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ + && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) +/* The character set is not based on ISO-646. */ +#error "gperf generated tables don't work with this execution character set. Please report a bug to ." +#endif + +#line 1 "./iconv_open-irix.gperf" +struct mapping { int standard_name; const char vendor_name[10 + 1]; }; + +#define TOTAL_KEYWORDS 19 +#define MIN_WORD_LENGTH 5 +#define MAX_WORD_LENGTH 11 +#define MIN_HASH_VALUE 5 +#define MAX_HASH_VALUE 23 +/* maximum key range = 19, duplicates = 0 */ + +#ifdef __GNUC__ +__inline +#else +#ifdef __cplusplus +inline +#endif +#endif +static unsigned int +mapping_hash (register const char *str, register unsigned int len) +{ + static const unsigned char asso_values[] = + { + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 8, 2, + 5, 12, 11, 0, 10, 9, 8, 7, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 0, 24, 0, + 24, 5, 24, 0, 24, 7, 24, 24, 24, 24, + 7, 24, 1, 0, 8, 24, 24, 0, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24 + }; + return len + asso_values[(unsigned char)str[len - 1]] + asso_values[(unsigned char)str[0]]; +} + +struct stringpool_t + { + char stringpool_str5[sizeof("CP855")]; + char stringpool_str6[sizeof("EUC-TW")]; + char stringpool_str7[sizeof("EUC-KR")]; + char stringpool_str8[sizeof("CP1251")]; + char stringpool_str9[sizeof("SHIFT_JIS")]; + char stringpool_str10[sizeof("ISO-8859-5")]; + char stringpool_str11[sizeof("ISO-8859-15")]; + char stringpool_str12[sizeof("ISO-8859-1")]; + char stringpool_str13[sizeof("EUC-JP")]; + char stringpool_str14[sizeof("KOI8-R")]; + char stringpool_str15[sizeof("ISO-8859-2")]; + char stringpool_str16[sizeof("GB2312")]; + char stringpool_str17[sizeof("ISO-8859-9")]; + char stringpool_str18[sizeof("ISO-8859-8")]; + char stringpool_str19[sizeof("ISO-8859-7")]; + char stringpool_str20[sizeof("ISO-8859-6")]; + char stringpool_str21[sizeof("ISO-8859-4")]; + char stringpool_str22[sizeof("ISO-8859-3")]; + char stringpool_str23[sizeof("TIS-620")]; + }; +static const struct stringpool_t stringpool_contents = + { + "CP855", + "EUC-TW", + "EUC-KR", + "CP1251", + "SHIFT_JIS", + "ISO-8859-5", + "ISO-8859-15", + "ISO-8859-1", + "EUC-JP", + "KOI8-R", + "ISO-8859-2", + "GB2312", + "ISO-8859-9", + "ISO-8859-8", + "ISO-8859-7", + "ISO-8859-6", + "ISO-8859-4", + "ISO-8859-3", + "TIS-620" + }; +#define stringpool ((const char *) &stringpool_contents) + +static const struct mapping mappings[] = + { + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 24 "./iconv_open-irix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str5, "DOS855"}, +#line 29 "./iconv_open-irix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str6, "eucTW"}, +#line 28 "./iconv_open-irix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str7, "eucKR"}, +#line 25 "./iconv_open-irix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str8, "WIN1251"}, +#line 30 "./iconv_open-irix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str9, "sjis"}, +#line 17 "./iconv_open-irix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str10, "ISO8859-5"}, +#line 22 "./iconv_open-irix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str11, "ISO8859-15"}, +#line 13 "./iconv_open-irix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str12, "ISO8859-1"}, +#line 27 "./iconv_open-irix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str13, "eucJP"}, +#line 23 "./iconv_open-irix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str14, "KOI8"}, +#line 14 "./iconv_open-irix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str15, "ISO8859-2"}, +#line 26 "./iconv_open-irix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str16, "eucCN"}, +#line 21 "./iconv_open-irix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str17, "ISO8859-9"}, +#line 20 "./iconv_open-irix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str18, "ISO8859-8"}, +#line 19 "./iconv_open-irix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str19, "ISO8859-7"}, +#line 18 "./iconv_open-irix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str20, "ISO8859-6"}, +#line 16 "./iconv_open-irix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str21, "ISO8859-4"}, +#line 15 "./iconv_open-irix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str22, "ISO8859-3"}, +#line 31 "./iconv_open-irix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str23, "TIS620"} + }; + +#ifdef __GNUC__ +__inline +#ifdef __GNUC_STDC_INLINE__ +__attribute__ ((__gnu_inline__)) +#endif +#endif +const struct mapping * +mapping_lookup (register const char *str, register unsigned int len) +{ + if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) + { + register int key = mapping_hash (str, len); + + if (key <= MAX_HASH_VALUE && key >= 0) + { + register int o = mappings[key].standard_name; + if (o >= 0) + { + register const char *s = o + stringpool; + + if (*str == *s && !strcmp (str + 1, s + 1)) + return &mappings[key]; + } + } + } + return 0; +} diff --git a/lib/iconv_open-osf.gperf b/lib/iconv_open-osf.gperf new file mode 100644 index 000000000..f468ff609 --- /dev/null +++ b/lib/iconv_open-osf.gperf @@ -0,0 +1,50 @@ +struct mapping { int standard_name; const char vendor_name[10 + 1]; }; +%struct-type +%language=ANSI-C +%define slot-name standard_name +%define hash-function-name mapping_hash +%define lookup-function-name mapping_lookup +%readonly-tables +%global-table +%define word-array-name mappings +%pic +%% +# On OSF/1 5.1, look in /usr/lib/nls/loc/iconv. +ISO-8859-1, "ISO8859-1" +ISO-8859-2, "ISO8859-2" +ISO-8859-3, "ISO8859-3" +ISO-8859-4, "ISO8859-4" +ISO-8859-5, "ISO8859-5" +ISO-8859-6, "ISO8859-6" +ISO-8859-7, "ISO8859-7" +ISO-8859-8, "ISO8859-8" +ISO-8859-9, "ISO8859-9" +ISO-8859-15, "ISO8859-15" +CP437, "cp437" +CP775, "cp775" +CP850, "cp850" +CP852, "cp852" +CP855, "cp855" +CP857, "cp857" +CP861, "cp861" +CP862, "cp862" +CP865, "cp865" +CP866, "cp866" +CP869, "cp869" +CP874, "cp874" +CP949, "KSC5601" +CP1250, "cp1250" +CP1251, "cp1251" +CP1252, "cp1252" +CP1253, "cp1253" +CP1254, "cp1254" +CP1255, "cp1255" +CP1256, "cp1256" +CP1257, "cp1257" +CP1258, "cp1258" +EUC-JP, "eucJP" +EUC-KR, "eucKR" +EUC-TW, "eucTW" +BIG5, "big5" +SHIFT_JIS, "SJIS" +TIS-620, "TACTIS" diff --git a/lib/iconv_open-osf.h b/lib/iconv_open-osf.h new file mode 100644 index 000000000..85e4c0f8f --- /dev/null +++ b/lib/iconv_open-osf.h @@ -0,0 +1,278 @@ +/* ANSI-C code produced by gperf version 3.0.3 */ +/* Command-line: gperf -m 10 ./iconv_open-osf.gperf */ +/* Computed positions: -k'4,$' */ + +#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ + && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ + && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ + && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ + && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ + && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ + && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ + && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ + && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ + && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ + && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ + && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ + && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ + && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ + && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ + && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ + && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ + && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ + && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ + && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ + && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ + && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ + && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) +/* The character set is not based on ISO-646. */ +#error "gperf generated tables don't work with this execution character set. Please report a bug to ." +#endif + +#line 1 "./iconv_open-osf.gperf" +struct mapping { int standard_name; const char vendor_name[10 + 1]; }; + +#define TOTAL_KEYWORDS 38 +#define MIN_WORD_LENGTH 4 +#define MAX_WORD_LENGTH 11 +#define MIN_HASH_VALUE 6 +#define MAX_HASH_VALUE 47 +/* maximum key range = 42, duplicates = 0 */ + +#ifdef __GNUC__ +__inline +#else +#ifdef __cplusplus +inline +#endif +#endif +static unsigned int +mapping_hash (register const char *str, register unsigned int len) +{ + static const unsigned char asso_values[] = + { + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 2, 29, + 24, 34, 31, 0, 15, 14, 10, 13, 2, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 7, 48, 48, 48, 48, 48, 48, + 11, 48, 2, 7, 48, 48, 48, 1, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48 + }; + return len + asso_values[(unsigned char)str[3]+3] + asso_values[(unsigned char)str[len - 1]]; +} + +struct stringpool_t + { + char stringpool_str6[sizeof("CP1255")]; + char stringpool_str7[sizeof("CP775")]; + char stringpool_str8[sizeof("CP1250")]; + char stringpool_str9[sizeof("EUC-TW")]; + char stringpool_str10[sizeof("EUC-KR")]; + char stringpool_str11[sizeof("TIS-620")]; + char stringpool_str12[sizeof("ISO-8859-5")]; + char stringpool_str13[sizeof("ISO-8859-15")]; + char stringpool_str14[sizeof("BIG5")]; + char stringpool_str15[sizeof("CP855")]; + char stringpool_str16[sizeof("CP1258")]; + char stringpool_str17[sizeof("CP850")]; + char stringpool_str18[sizeof("CP865")]; + char stringpool_str19[sizeof("EUC-JP")]; + char stringpool_str20[sizeof("CP1257")]; + char stringpool_str21[sizeof("CP1256")]; + char stringpool_str22[sizeof("ISO-8859-8")]; + char stringpool_str23[sizeof("SHIFT_JIS")]; + char stringpool_str25[sizeof("ISO-8859-9")]; + char stringpool_str26[sizeof("ISO-8859-7")]; + char stringpool_str27[sizeof("ISO-8859-6")]; + char stringpool_str29[sizeof("CP857")]; + char stringpool_str30[sizeof("CP1252")]; + char stringpool_str31[sizeof("CP869")]; + char stringpool_str32[sizeof("CP949")]; + char stringpool_str33[sizeof("CP866")]; + char stringpool_str34[sizeof("CP437")]; + char stringpool_str35[sizeof("CP1251")]; + char stringpool_str36[sizeof("ISO-8859-2")]; + char stringpool_str37[sizeof("CP1254")]; + char stringpool_str38[sizeof("CP874")]; + char stringpool_str39[sizeof("CP852")]; + char stringpool_str40[sizeof("CP1253")]; + char stringpool_str41[sizeof("ISO-8859-1")]; + char stringpool_str42[sizeof("CP862")]; + char stringpool_str43[sizeof("ISO-8859-4")]; + char stringpool_str46[sizeof("ISO-8859-3")]; + char stringpool_str47[sizeof("CP861")]; + }; +static const struct stringpool_t stringpool_contents = + { + "CP1255", + "CP775", + "CP1250", + "EUC-TW", + "EUC-KR", + "TIS-620", + "ISO-8859-5", + "ISO-8859-15", + "BIG5", + "CP855", + "CP1258", + "CP850", + "CP865", + "EUC-JP", + "CP1257", + "CP1256", + "ISO-8859-8", + "SHIFT_JIS", + "ISO-8859-9", + "ISO-8859-7", + "ISO-8859-6", + "CP857", + "CP1252", + "CP869", + "CP949", + "CP866", + "CP437", + "CP1251", + "ISO-8859-2", + "CP1254", + "CP874", + "CP852", + "CP1253", + "ISO-8859-1", + "CP862", + "ISO-8859-4", + "ISO-8859-3", + "CP861" + }; +#define stringpool ((const char *) &stringpool_contents) + +static const struct mapping mappings[] = + { + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 41 "./iconv_open-osf.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str6, "cp1255"}, +#line 24 "./iconv_open-osf.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str7, "cp775"}, +#line 36 "./iconv_open-osf.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str8, "cp1250"}, +#line 47 "./iconv_open-osf.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str9, "eucTW"}, +#line 46 "./iconv_open-osf.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str10, "eucKR"}, +#line 50 "./iconv_open-osf.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str11, "TACTIS"}, +#line 17 "./iconv_open-osf.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str12, "ISO8859-5"}, +#line 22 "./iconv_open-osf.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str13, "ISO8859-15"}, +#line 48 "./iconv_open-osf.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str14, "big5"}, +#line 27 "./iconv_open-osf.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str15, "cp855"}, +#line 44 "./iconv_open-osf.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str16, "cp1258"}, +#line 25 "./iconv_open-osf.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str17, "cp850"}, +#line 31 "./iconv_open-osf.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str18, "cp865"}, +#line 45 "./iconv_open-osf.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str19, "eucJP"}, +#line 43 "./iconv_open-osf.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str20, "cp1257"}, +#line 42 "./iconv_open-osf.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str21, "cp1256"}, +#line 20 "./iconv_open-osf.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str22, "ISO8859-8"}, +#line 49 "./iconv_open-osf.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str23, "SJIS"}, + {-1}, +#line 21 "./iconv_open-osf.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str25, "ISO8859-9"}, +#line 19 "./iconv_open-osf.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str26, "ISO8859-7"}, +#line 18 "./iconv_open-osf.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str27, "ISO8859-6"}, + {-1}, +#line 28 "./iconv_open-osf.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str29, "cp857"}, +#line 38 "./iconv_open-osf.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str30, "cp1252"}, +#line 33 "./iconv_open-osf.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str31, "cp869"}, +#line 35 "./iconv_open-osf.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str32, "KSC5601"}, +#line 32 "./iconv_open-osf.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str33, "cp866"}, +#line 23 "./iconv_open-osf.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str34, "cp437"}, +#line 37 "./iconv_open-osf.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str35, "cp1251"}, +#line 14 "./iconv_open-osf.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str36, "ISO8859-2"}, +#line 40 "./iconv_open-osf.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str37, "cp1254"}, +#line 34 "./iconv_open-osf.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str38, "cp874"}, +#line 26 "./iconv_open-osf.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str39, "cp852"}, +#line 39 "./iconv_open-osf.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str40, "cp1253"}, +#line 13 "./iconv_open-osf.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str41, "ISO8859-1"}, +#line 30 "./iconv_open-osf.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str42, "cp862"}, +#line 16 "./iconv_open-osf.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str43, "ISO8859-4"}, + {-1}, {-1}, +#line 15 "./iconv_open-osf.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str46, "ISO8859-3"}, +#line 29 "./iconv_open-osf.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str47, "cp861"} + }; + +#ifdef __GNUC__ +__inline +#ifdef __GNUC_STDC_INLINE__ +__attribute__ ((__gnu_inline__)) +#endif +#endif +const struct mapping * +mapping_lookup (register const char *str, register unsigned int len) +{ + if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) + { + register int key = mapping_hash (str, len); + + if (key <= MAX_HASH_VALUE && key >= 0) + { + register int o = mappings[key].standard_name; + if (o >= 0) + { + register const char *s = o + stringpool; + + if (*str == *s && !strcmp (str + 1, s + 1)) + return &mappings[key]; + } + } + } + return 0; +} diff --git a/lib/iconv_open.c b/lib/iconv_open.c new file mode 100644 index 000000000..3d873acd6 --- /dev/null +++ b/lib/iconv_open.c @@ -0,0 +1,172 @@ +/* Character set conversion. + Copyright (C) 2007 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2, 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License along + with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include + +/* Specification. */ +#include + +#include +#include +#include "c-ctype.h" +#include "c-strcase.h" + +#define SIZEOF(a) (sizeof(a) / sizeof(a[0])) + +/* Namespace cleanliness. */ +#define mapping_lookup rpl_iconv_open_mapping_lookup + +/* The macro ICONV_FLAVOR is defined to one of these or undefined. */ + +#define ICONV_FLAVOR_AIX "iconv_open-aix.h" +#define ICONV_FLAVOR_HPUX "iconv_open-hpux.h" +#define ICONV_FLAVOR_IRIX "iconv_open-irix.h" +#define ICONV_FLAVOR_OSF "iconv_open-osf.h" + +#ifdef ICONV_FLAVOR +# include ICONV_FLAVOR +#endif + +iconv_t +rpl_iconv_open (const char *tocode, const char *fromcode) +#undef iconv_open +{ + char fromcode_upper[32]; + char tocode_upper[32]; + char *fromcode_upper_end; + char *tocode_upper_end; + +#if REPLACE_ICONV_UTF + /* Special handling of conversion between UTF-8 and UTF-{16,32}{BE,LE}. + Do this here, before calling the real iconv_open(), because OSF/1 5.1 + iconv() to these encoding inserts a BOM, which is wrong. + We do not need to handle conversion between arbitrary encodings and + UTF-{16,32}{BE,LE}, because the 'striconveh' module implements two-step + conversion throough UTF-8. + The _ICONV_* constants are chosen to be disjoint from any iconv_t + returned by the system's iconv_open() functions. Recall that iconv_t + is a scalar type. */ + if (c_toupper (fromcode[0]) == 'U' + && c_toupper (fromcode[1]) == 'T' + && c_toupper (fromcode[2]) == 'F' + && fromcode[3] == '-') + { + if (c_toupper (tocode[0]) == 'U' + && c_toupper (tocode[1]) == 'T' + && c_toupper (tocode[2]) == 'F' + && tocode[3] == '-') + { + if (strcmp (fromcode + 4, "8") == 0) + { + if (c_strcasecmp (tocode + 4, "16BE") == 0) + return _ICONV_UTF8_UTF16BE; + if (c_strcasecmp (tocode + 4, "16LE") == 0) + return _ICONV_UTF8_UTF16LE; + if (c_strcasecmp (tocode + 4, "32BE") == 0) + return _ICONV_UTF8_UTF32BE; + if (c_strcasecmp (tocode + 4, "32LE") == 0) + return _ICONV_UTF8_UTF32LE; + } + else if (strcmp (tocode + 4, "8") == 0) + { + if (c_strcasecmp (fromcode + 4, "16BE") == 0) + return _ICONV_UTF16BE_UTF8; + if (c_strcasecmp (fromcode + 4, "16LE") == 0) + return _ICONV_UTF16LE_UTF8; + if (c_strcasecmp (fromcode + 4, "32BE") == 0) + return _ICONV_UTF32BE_UTF8; + if (c_strcasecmp (fromcode + 4, "32LE") == 0) + return _ICONV_UTF32LE_UTF8; + } + } + } +#endif + + /* Do *not* add special support for 8-bit encodings like ASCII or ISO-8859-1 + here. This would lead to programs that work in some locales (such as the + "C" or "en_US" locales) but do not work in East Asian locales. It is + better if programmers make their programs depend on GNU libiconv (except + on glibc systems), e.g. by using the AM_ICONV macro and documenting the + dependency in an INSTALL or DEPENDENCIES file. */ + + /* Try with the original names first. + This covers the case when fromcode or tocode is a lowercase encoding name + that is understood by the system's iconv_open but not listed in our + mappings table. */ + { + iconv_t cd = iconv_open (tocode, fromcode); + if (cd != (iconv_t)(-1)) + return cd; + } + + /* Convert the encodings to upper case, because + 1. in the arguments of iconv_open() on AIX, HP-UX, and OSF/1 the case + matters, + 2. it makes searching in the table faster. */ + { + const char *p = fromcode; + char *q = fromcode_upper; + while ((*q = c_toupper (*p)) != '\0') + { + p++; + q++; + if (q == &fromcode_upper[SIZEOF (fromcode_upper)]) + { + errno = EINVAL; + return (iconv_t)(-1); + } + } + fromcode_upper_end = q; + } + + { + const char *p = tocode; + char *q = tocode_upper; + while ((*q = c_toupper (*p)) != '\0') + { + p++; + q++; + if (q == &tocode_upper[SIZEOF (tocode_upper)]) + { + errno = EINVAL; + return (iconv_t)(-1); + } + } + tocode_upper_end = q; + } + +#ifdef ICONV_FLAVOR + /* Apply the mappings. */ + { + const struct mapping *m = + mapping_lookup (fromcode_upper, fromcode_upper_end - fromcode_upper); + + fromcode = (m != NULL ? m->vendor_name : fromcode_upper); + } + { + const struct mapping *m = + mapping_lookup (tocode_upper, tocode_upper_end - tocode_upper); + + tocode = (m != NULL ? m->vendor_name : tocode_upper); + } +#else + fromcode = fromcode_upper; + tocode = tocode_upper; +#endif + + return iconv_open (tocode, fromcode); +} diff --git a/lib/iconveh.h b/lib/iconveh.h new file mode 100644 index 000000000..06cda52e8 --- /dev/null +++ b/lib/iconveh.h @@ -0,0 +1,41 @@ +/* Character set conversion handler type. + Copyright (C) 2001-2007, 2009 Free Software Foundation, Inc. + Written by Bruno Haible. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#ifndef _ICONVEH_H +#define _ICONVEH_H + + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Handling of unconvertible characters. */ +enum iconv_ilseq_handler +{ + iconveh_error, /* return and set errno = EILSEQ */ + iconveh_question_mark, /* use one '?' per unconvertible character */ + iconveh_escape_sequence /* use escape sequence \uxxxx or \Uxxxxxxxx */ +}; + + +#ifdef __cplusplus +} +#endif + + +#endif /* _ICONVEH_H */ diff --git a/lib/localcharset.c b/lib/localcharset.c index c3e393735..93da17077 100644 --- a/lib/localcharset.c +++ b/lib/localcharset.c @@ -1,6 +1,6 @@ /* Determine a canonical name for the current locale's character encoding. - Copyright (C) 2000-2006, 2008 Free Software Foundation, Inc. + Copyright (C) 2000-2006, 2008-2009 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by @@ -28,6 +28,10 @@ #include #include +#if defined __APPLE__ && defined __MACH__ && HAVE_LANGINFO_CODESET +# define DARWIN7 /* Darwin 7 or newer, i.e. MacOS X 10.3 or newer */ +#endif + #if defined _WIN32 || defined __WIN32__ # define WIN32_NATIVE #endif @@ -112,7 +116,7 @@ get_charset_aliases (void) cp = charset_aliases; if (cp == NULL) { -#if !(defined VMS || defined WIN32_NATIVE || defined __CYGWIN__) +#if !(defined DARWIN7 || defined VMS || defined WIN32_NATIVE || defined __CYGWIN__) FILE *fp; const char *dir; const char *base = "charset.alias"; @@ -213,6 +217,39 @@ get_charset_aliases (void) #else +# if defined DARWIN7 + /* To avoid the trouble of installing a file that is shared by many + GNU packages -- many packaging systems have problems with this --, + simply inline the aliases here. */ + cp = "ISO8859-1" "\0" "ISO-8859-1" "\0" + "ISO8859-2" "\0" "ISO-8859-2" "\0" + "ISO8859-4" "\0" "ISO-8859-4" "\0" + "ISO8859-5" "\0" "ISO-8859-5" "\0" + "ISO8859-7" "\0" "ISO-8859-7" "\0" + "ISO8859-9" "\0" "ISO-8859-9" "\0" + "ISO8859-13" "\0" "ISO-8859-13" "\0" + "ISO8859-15" "\0" "ISO-8859-15" "\0" + "KOI8-R" "\0" "KOI8-R" "\0" + "KOI8-U" "\0" "KOI8-U" "\0" + "CP866" "\0" "CP866" "\0" + "CP949" "\0" "CP949" "\0" + "CP1131" "\0" "CP1131" "\0" + "CP1251" "\0" "CP1251" "\0" + "eucCN" "\0" "GB2312" "\0" + "GB2312" "\0" "GB2312" "\0" + "eucJP" "\0" "EUC-JP" "\0" + "eucKR" "\0" "EUC-KR" "\0" + "Big5" "\0" "BIG5" "\0" + "Big5HKSCS" "\0" "BIG5-HKSCS" "\0" + "GBK" "\0" "GBK" "\0" + "GB18030" "\0" "GB18030" "\0" + "SJIS" "\0" "SHIFT_JIS" "\0" + "ARMSCII-8" "\0" "ARMSCII-8" "\0" + "PT154" "\0" "PT154" "\0" + /*"ISCII-DEV" "\0" "?" "\0"*/ + "*" "\0" "UTF-8" "\0"; +# endif + # if defined VMS /* To avoid the troubles of an extra file charset.alias_vms in the sources of many GNU packages, simply inline the aliases here. */ diff --git a/lib/malloc.c b/lib/malloc.c new file mode 100644 index 000000000..9111c7a1e --- /dev/null +++ b/lib/malloc.c @@ -0,0 +1,57 @@ +/* malloc() function that is glibc compatible. + + Copyright (C) 1997, 1998, 2006, 2007 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2, 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* written by Jim Meyering and Bruno Haible */ + +#include +/* Only the AC_FUNC_MALLOC macro defines 'malloc' already in config.h. */ +#ifdef malloc +# define NEED_MALLOC_GNU +# undef malloc +#endif + +/* Specification. */ +#include + +#include + +/* Call the system's malloc below. */ +#undef malloc + +/* Allocate an N-byte block of memory from the heap. + If N is zero, allocate a 1-byte block. */ + +void * +rpl_malloc (size_t n) +{ + void *result; + +#ifdef NEED_MALLOC_GNU + if (n == 0) + n = 1; +#endif + + result = malloc (n); + +#if !HAVE_MALLOC_POSIX + if (result == NULL) + errno = ENOMEM; +#endif + + return result; +} diff --git a/lib/malloca.c b/lib/malloca.c new file mode 100644 index 000000000..7905e6152 --- /dev/null +++ b/lib/malloca.c @@ -0,0 +1,137 @@ +/* Safe automatic memory allocation. + Copyright (C) 2003, 2006-2007 Free Software Foundation, Inc. + Written by Bruno Haible , 2003. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2, 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include + +/* Specification. */ +#include "malloca.h" + +/* The speed critical point in this file is freea() applied to an alloca() + result: it must be fast, to match the speed of alloca(). The speed of + mmalloca() and freea() in the other case are not critical, because they + are only invoked for big memory sizes. */ + +#if HAVE_ALLOCA + +/* Store the mmalloca() results in a hash table. This is needed to reliably + distinguish a mmalloca() result and an alloca() result. + + Although it is possible that the same pointer is returned by alloca() and + by mmalloca() at different times in the same application, it does not lead + to a bug in freea(), because: + - Before a pointer returned by alloca() can point into malloc()ed memory, + the function must return, and once this has happened the programmer must + not call freea() on it anyway. + - Before a pointer returned by mmalloca() can point into the stack, it + must be freed. The only function that can free it is freea(), and + when freea() frees it, it also removes it from the hash table. */ + +#define MAGIC_NUMBER 0x1415fb4a +#define MAGIC_SIZE sizeof (int) +/* This is how the header info would look like without any alignment + considerations. */ +struct preliminary_header { void *next; char room[MAGIC_SIZE]; }; +/* But the header's size must be a multiple of sa_alignment_max. */ +#define HEADER_SIZE \ + (((sizeof (struct preliminary_header) + sa_alignment_max - 1) / sa_alignment_max) * sa_alignment_max) +struct header { void *next; char room[HEADER_SIZE - sizeof (struct preliminary_header) + MAGIC_SIZE]; }; +/* Verify that HEADER_SIZE == sizeof (struct header). */ +typedef int verify1[2 * (HEADER_SIZE == sizeof (struct header)) - 1]; +/* We make the hash table quite big, so that during lookups the probability + of empty hash buckets is quite high. There is no need to make the hash + table resizable, because when the hash table gets filled so much that the + lookup becomes slow, it means that the application has memory leaks. */ +#define HASH_TABLE_SIZE 257 +static void * mmalloca_results[HASH_TABLE_SIZE]; + +#endif + +void * +mmalloca (size_t n) +{ +#if HAVE_ALLOCA + /* Allocate one more word, that serves as an indicator for malloc()ed + memory, so that freea() of an alloca() result is fast. */ + size_t nplus = n + HEADER_SIZE; + + if (nplus >= n) + { + char *p = (char *) malloc (nplus); + + if (p != NULL) + { + size_t slot; + + p += HEADER_SIZE; + + /* Put a magic number into the indicator word. */ + ((int *) p)[-1] = MAGIC_NUMBER; + + /* Enter p into the hash table. */ + slot = (unsigned long) p % HASH_TABLE_SIZE; + ((struct header *) (p - HEADER_SIZE))->next = mmalloca_results[slot]; + mmalloca_results[slot] = p; + + return p; + } + } + /* Out of memory. */ + return NULL; +#else +# if !MALLOC_0_IS_NONNULL + if (n == 0) + n = 1; +# endif + return malloc (n); +#endif +} + +#if HAVE_ALLOCA +void +freea (void *p) +{ + /* mmalloca() may have returned NULL. */ + if (p != NULL) + { + /* Attempt to quickly distinguish the mmalloca() result - which has + a magic indicator word - and the alloca() result - which has an + uninitialized indicator word. It is for this test that sa_increment + additional bytes are allocated in the alloca() case. */ + if (((int *) p)[-1] == MAGIC_NUMBER) + { + /* Looks like a mmalloca() result. To see whether it really is one, + perform a lookup in the hash table. */ + size_t slot = (unsigned long) p % HASH_TABLE_SIZE; + void **chain = &mmalloca_results[slot]; + for (; *chain != NULL;) + { + if (*chain == p) + { + /* Found it. Remove it from the hash table and free it. */ + char *p_begin = (char *) p - HEADER_SIZE; + *chain = ((struct header *) p_begin)->next; + free (p_begin); + return; + } + chain = &((struct header *) ((char *) *chain - HEADER_SIZE))->next; + } + } + /* At this point, we know it was not a mmalloca() result. */ + } +} +#endif diff --git a/lib/malloca.h b/lib/malloca.h new file mode 100644 index 000000000..7d92b0af5 --- /dev/null +++ b/lib/malloca.h @@ -0,0 +1,134 @@ +/* Safe automatic memory allocation. + Copyright (C) 2003-2007 Free Software Foundation, Inc. + Written by Bruno Haible , 2003. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2, 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef _MALLOCA_H +#define _MALLOCA_H + +#include +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif + + +/* safe_alloca(N) is equivalent to alloca(N) when it is safe to call + alloca(N); otherwise it returns NULL. It either returns N bytes of + memory allocated on the stack, that lasts until the function returns, + or NULL. + Use of safe_alloca should be avoided: + - inside arguments of function calls - undefined behaviour, + - in inline functions - the allocation may actually last until the + calling function returns. +*/ +#if HAVE_ALLOCA +/* The OS usually guarantees only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + allocate anything larger than 4096 bytes. Also care for the possibility + of a few compiler-allocated temporary stack slots. + This must be a macro, not an inline function. */ +# define safe_alloca(N) ((N) < 4032 ? alloca (N) : NULL) +#else +# define safe_alloca(N) ((void) (N), NULL) +#endif + +/* malloca(N) is a safe variant of alloca(N). It allocates N bytes of + memory allocated on the stack, that must be freed using freea() before + the function returns. Upon failure, it returns NULL. */ +#if HAVE_ALLOCA +# define malloca(N) \ + ((N) < 4032 - sa_increment \ + ? (void *) ((char *) alloca ((N) + sa_increment) + sa_increment) \ + : mmalloca (N)) +#else +# define malloca(N) \ + mmalloca (N) +#endif +extern void * mmalloca (size_t n); + +/* Free a block of memory allocated through malloca(). */ +#if HAVE_ALLOCA +extern void freea (void *p); +#else +# define freea free +#endif + +/* nmalloca(N,S) is an overflow-safe variant of malloca (N * S). + It allocates an array of N objects, each with S bytes of memory, + on the stack. S must be positive and N must be nonnegative. + The array must be freed using freea() before the function returns. */ +#if 1 +/* Cf. the definition of xalloc_oversized. */ +# define nmalloca(n, s) \ + ((n) > (size_t) (sizeof (ptrdiff_t) <= sizeof (size_t) ? -1 : -2) / (s) \ + ? NULL \ + : malloca ((n) * (s))) +#else +extern void * nmalloca (size_t n, size_t s); +#endif + + +#ifdef __cplusplus +} +#endif + + +/* ------------------- Auxiliary, non-public definitions ------------------- */ + +/* Determine the alignment of a type at compile time. */ +#if defined __GNUC__ +# define sa_alignof __alignof__ +#elif defined __cplusplus + template struct sa_alignof_helper { char __slot1; type __slot2; }; +# define sa_alignof(type) offsetof (sa_alignof_helper, __slot2) +#elif defined __hpux + /* Work around a HP-UX 10.20 cc bug with enums constants defined as offsetof + values. */ +# define sa_alignof(type) (sizeof (type) <= 4 ? 4 : 8) +#elif defined _AIX + /* Work around an AIX 3.2.5 xlc bug with enums constants defined as offsetof + values. */ +# define sa_alignof(type) (sizeof (type) <= 4 ? 4 : 8) +#else +# define sa_alignof(type) offsetof (struct { char __slot1; type __slot2; }, __slot2) +#endif + +enum +{ +/* The desired alignment of memory allocations is the maximum alignment + among all elementary types. */ + sa_alignment_long = sa_alignof (long), + sa_alignment_double = sa_alignof (double), +#if HAVE_LONG_LONG_INT + sa_alignment_longlong = sa_alignof (long long), +#endif + sa_alignment_longdouble = sa_alignof (long double), + sa_alignment_max = ((sa_alignment_long - 1) | (sa_alignment_double - 1) +#if HAVE_LONG_LONG_INT + | (sa_alignment_longlong - 1) +#endif + | (sa_alignment_longdouble - 1) + ) + 1, +/* The increment that guarantees room for a magic word must be >= sizeof (int) + and a multiple of sa_alignment_max. */ + sa_increment = ((sizeof (int) + sa_alignment_max - 1) / sa_alignment_max) * sa_alignment_max +}; + +#endif /* _MALLOCA_H */ diff --git a/lib/malloca.valgrind b/lib/malloca.valgrind new file mode 100644 index 000000000..52f0a50f5 --- /dev/null +++ b/lib/malloca.valgrind @@ -0,0 +1,7 @@ +# Suppress a valgrind message about use of uninitialized memory in freea(). +# This use is OK because it provides only a speedup. +{ + freea + Memcheck:Cond + fun:freea +} diff --git a/lib/mbrtowc.c b/lib/mbrtowc.c index 17b3de53b..7b528e807 100644 --- a/lib/mbrtowc.c +++ b/lib/mbrtowc.c @@ -1,5 +1,5 @@ /* Convert multibyte character to wide character. - Copyright (C) 1999-2002, 2005-2008 Free Software Foundation, Inc. + Copyright (C) 1999-2002, 2005-2009 Free Software Foundation, Inc. Written by Bruno Haible , 2008. This program is free software: you can redistribute it and/or modify @@ -89,7 +89,7 @@ mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps) return (size_t)(-1); } - /* Here 0 < m ≤ 4. */ + /* Here m > 0. */ # if __GLIBC__ /* Work around bug */ @@ -118,7 +118,7 @@ mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps) lack mbrtowc(), we use the second approach. The possible encodings are: - 8-bit encodings, - - EUC-JP, EUC-KR, GB2312, EUC-TW, BIG5, SJIS, + - EUC-JP, EUC-KR, GB2312, EUC-TW, BIG5, GB18030, SJIS, - UTF-8. Use specialized code for each. */ if (m >= 4 || m >= MB_CUR_MAX) @@ -238,6 +238,39 @@ mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps) } goto invalid; } + if (STREQ (encoding, "GB18030", 'G', 'B', '1', '8', '0', '3', '0', 0, 0)) + { + if (m == 1) + { + unsigned char c = (unsigned char) p[0]; + + if ((c >= 0x90 && c <= 0xe3) || (c >= 0xf8 && c <= 0xfe)) + goto incomplete; + } + else /* m == 2 || m == 3 */ + { + unsigned char c = (unsigned char) p[0]; + + if (c >= 0x90 && c <= 0xe3) + { + unsigned char c2 = (unsigned char) p[1]; + + if (c2 >= 0x30 && c2 <= 0x39) + { + if (m == 2) + goto incomplete; + else /* m == 3 */ + { + unsigned char c3 = (unsigned char) p[2]; + + if (c3 >= 0x81 && c3 <= 0xfe) + goto incomplete; + } + } + } + } + goto invalid; + } if (STREQ (encoding, "SJIS", 'S', 'J', 'I', 'S', 0, 0, 0, 0, 0)) { if (m == 1) @@ -258,10 +291,14 @@ mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps) incomplete: { size_t k = nstate; - /* Here 0 < k < m < 4. */ + /* Here 0 <= k < m < 4. */ pstate[++k] = s[0]; if (k < m) - pstate[++k] = s[1]; + { + pstate[++k] = s[1]; + if (k < m) + pstate[++k] = s[2]; + } if (k != m) abort (); } diff --git a/lib/memchr.c b/lib/memchr.c new file mode 100644 index 000000000..3ea1d5bac --- /dev/null +++ b/lib/memchr.c @@ -0,0 +1,172 @@ +/* Copyright (C) 1991, 1993, 1996, 1997, 1999, 2000, 2003, 2004, 2006, 2008 + Free Software Foundation, Inc. + + Based on strlen implementation by Torbjorn Granlund (tege@sics.se), + with help from Dan Sahlin (dan@sics.se) and + commentary by Jim Blandy (jimb@ai.mit.edu); + adaptation to memchr suggested by Dick Karpinski (dick@cca.ucsf.edu), + and implemented by Roland McGrath (roland@ai.mit.edu). + +NOTE: The canonical source of this file is maintained with the GNU C Library. +Bugs can be reported to bug-glibc@prep.ai.mit.edu. + +This program is free software: you can redistribute it and/or modify it +under the terms of the GNU Lesser General Public License as published by the +Free Software Foundation; either version 3 of the License, or 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 Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program. If not, see . */ + +#ifndef _LIBC +# include +#endif + +#include + +#include + +#if defined _LIBC +# include +#else +# define reg_char char +#endif + +#include + +#if HAVE_BP_SYM_H || defined _LIBC +# include +#else +# define BP_SYM(sym) sym +#endif + +#undef __memchr +#ifdef _LIBC +# undef memchr +#endif + +#ifndef weak_alias +# define __memchr memchr +#endif + +/* Search no more than N bytes of S for C. */ +void * +__memchr (void const *s, int c_in, size_t n) +{ + /* On 32-bit hardware, choosing longword to be a 32-bit unsigned + long instead of a 64-bit uintmax_t tends to give better + performance. On 64-bit hardware, unsigned long is generally 64 + bits already. Change this typedef to experiment with + performance. */ + typedef unsigned long int longword; + + const unsigned char *char_ptr; + const longword *longword_ptr; + longword repeated_one; + longword repeated_c; + unsigned reg_char c; + + c = (unsigned char) c_in; + + /* Handle the first few bytes by reading one byte at a time. + Do this until CHAR_PTR is aligned on a longword boundary. */ + for (char_ptr = (const unsigned char *) s; + n > 0 && (size_t) char_ptr % sizeof (longword) != 0; + --n, ++char_ptr) + if (*char_ptr == c) + return (void *) char_ptr; + + longword_ptr = (const longword *) char_ptr; + + /* All these elucidatory comments refer to 4-byte longwords, + but the theory applies equally well to any size longwords. */ + + /* Compute auxiliary longword values: + repeated_one is a value which has a 1 in every byte. + repeated_c has c in every byte. */ + repeated_one = 0x01010101; + repeated_c = c | (c << 8); + repeated_c |= repeated_c << 16; + if (0xffffffffU < (longword) -1) + { + repeated_one |= repeated_one << 31 << 1; + repeated_c |= repeated_c << 31 << 1; + if (8 < sizeof (longword)) + { + size_t i; + + for (i = 64; i < sizeof (longword) * 8; i *= 2) + { + repeated_one |= repeated_one << i; + repeated_c |= repeated_c << i; + } + } + } + + /* Instead of the traditional loop which tests each byte, we will test a + longword at a time. The tricky part is testing if *any of the four* + bytes in the longword in question are equal to c. We first use an xor + with repeated_c. This reduces the task to testing whether *any of the + four* bytes in longword1 is zero. + + We compute tmp = + ((longword1 - repeated_one) & ~longword1) & (repeated_one << 7). + That is, we perform the following operations: + 1. Subtract repeated_one. + 2. & ~longword1. + 3. & a mask consisting of 0x80 in every byte. + Consider what happens in each byte: + - If a byte of longword1 is zero, step 1 and 2 transform it into 0xff, + and step 3 transforms it into 0x80. A carry can also be propagated + to more significant bytes. + - If a byte of longword1 is nonzero, let its lowest 1 bit be at + position k (0 <= k <= 7); so the lowest k bits are 0. After step 1, + the byte ends in a single bit of value 0 and k bits of value 1. + After step 2, the result is just k bits of value 1: 2^k - 1. After + step 3, the result is 0. And no carry is produced. + So, if longword1 has only non-zero bytes, tmp is zero. + Whereas if longword1 has a zero byte, call j the position of the least + significant zero byte. Then the result has a zero at positions 0, ..., + j-1 and a 0x80 at position j. We cannot predict the result at the more + significant bytes (positions j+1..3), but it does not matter since we + already have a non-zero bit at position 8*j+7. + + So, the test whether any byte in longword1 is zero is equivalent to + testing whether tmp is nonzero. */ + + while (n >= sizeof (longword)) + { + longword longword1 = *longword_ptr ^ repeated_c; + + if ((((longword1 - repeated_one) & ~longword1) + & (repeated_one << 7)) != 0) + break; + longword_ptr++; + n -= sizeof (longword); + } + + char_ptr = (const unsigned char *) longword_ptr; + + /* At this point, we know that either n < sizeof (longword), or one of the + sizeof (longword) bytes starting at char_ptr is == c. On little-endian + machines, we could determine the first such byte without any further + memory accesses, just by looking at the tmp result from the last loop + iteration. But this does not work on big-endian machines. Choose code + that works in both cases. */ + + for (; n > 0; --n, ++char_ptr) + { + if (*char_ptr == c) + return (void *) char_ptr; + } + + return NULL; +} +#ifdef weak_alias +weak_alias (__memchr, BP_SYM (memchr)) +#endif diff --git a/lib/memchr.valgrind b/lib/memchr.valgrind new file mode 100644 index 000000000..60f247e10 --- /dev/null +++ b/lib/memchr.valgrind @@ -0,0 +1,14 @@ +# Suppress a valgrind message about use of uninitialized memory in memchr(). +# POSIX states that when the character is found, memchr must not read extra +# bytes in an overestimated length (for example, where memchr is used to +# implement strnlen). However, we use a safe word read to provide a speedup. +{ + memchr-value4 + Memcheck:Value4 + fun:rpl_memchr +} +{ + memchr-value8 + Memcheck:Value8 + fun:rpl_memchr +} diff --git a/lib/pathmax.h b/lib/pathmax.h new file mode 100644 index 000000000..a5d433560 --- /dev/null +++ b/lib/pathmax.h @@ -0,0 +1,47 @@ +/* Define PATH_MAX somehow. Requires sys/types.h. + Copyright (C) 1992, 1999, 2001, 2003, 2005, 2009 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2, 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef _PATHMAX_H +# define _PATHMAX_H + +# include + +# include + +# ifndef _POSIX_PATH_MAX +# define _POSIX_PATH_MAX 256 +# endif + +# if !defined PATH_MAX && defined _PC_PATH_MAX && defined HAVE_PATHCONF +# define PATH_MAX (pathconf ("/", _PC_PATH_MAX) < 1 ? 1024 \ + : pathconf ("/", _PC_PATH_MAX)) +# endif + +/* Don't include sys/param.h if it already has been. */ +# if defined HAVE_SYS_PARAM_H && !defined PATH_MAX && !defined MAXPATHLEN +# include +# endif + +# if !defined PATH_MAX && defined MAXPATHLEN +# define PATH_MAX MAXPATHLEN +# endif + +# ifndef PATH_MAX +# define PATH_MAX _POSIX_PATH_MAX +# endif + +#endif /* _PATHMAX_H */ diff --git a/lib/printf-args.c b/lib/printf-args.c new file mode 100644 index 000000000..c31d2042e --- /dev/null +++ b/lib/printf-args.c @@ -0,0 +1,187 @@ +/* Decomposed printf argument list. + Copyright (C) 1999, 2002-2003, 2005-2007 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2, 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License along + with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* This file can be parametrized with the following macros: + ENABLE_UNISTDIO Set to 1 to enable the unistdio extensions. + PRINTF_FETCHARGS Name of the function to be defined. + STATIC Set to 'static' to declare the function static. */ + +#ifndef PRINTF_FETCHARGS +# include +#endif + +/* Specification. */ +#ifndef PRINTF_FETCHARGS +# include "printf-args.h" +#endif + +#ifdef STATIC +STATIC +#endif +int +PRINTF_FETCHARGS (va_list args, arguments *a) +{ + size_t i; + argument *ap; + + for (i = 0, ap = &a->arg[0]; i < a->count; i++, ap++) + switch (ap->type) + { + case TYPE_SCHAR: + ap->a.a_schar = va_arg (args, /*signed char*/ int); + break; + case TYPE_UCHAR: + ap->a.a_uchar = va_arg (args, /*unsigned char*/ int); + break; + case TYPE_SHORT: + ap->a.a_short = va_arg (args, /*short*/ int); + break; + case TYPE_USHORT: + ap->a.a_ushort = va_arg (args, /*unsigned short*/ int); + break; + case TYPE_INT: + ap->a.a_int = va_arg (args, int); + break; + case TYPE_UINT: + ap->a.a_uint = va_arg (args, unsigned int); + break; + case TYPE_LONGINT: + ap->a.a_longint = va_arg (args, long int); + break; + case TYPE_ULONGINT: + ap->a.a_ulongint = va_arg (args, unsigned long int); + break; +#if HAVE_LONG_LONG_INT + case TYPE_LONGLONGINT: + ap->a.a_longlongint = va_arg (args, long long int); + break; + case TYPE_ULONGLONGINT: + ap->a.a_ulonglongint = va_arg (args, unsigned long long int); + break; +#endif + case TYPE_DOUBLE: + ap->a.a_double = va_arg (args, double); + break; + case TYPE_LONGDOUBLE: + ap->a.a_longdouble = va_arg (args, long double); + break; + case TYPE_CHAR: + ap->a.a_char = va_arg (args, int); + break; +#if HAVE_WINT_T + case TYPE_WIDE_CHAR: + /* Although ISO C 99 7.24.1.(2) says that wint_t is "unchanged by + default argument promotions", this is not the case in mingw32, + where wint_t is 'unsigned short'. */ + ap->a.a_wide_char = + (sizeof (wint_t) < sizeof (int) + ? va_arg (args, int) + : va_arg (args, wint_t)); + break; +#endif + case TYPE_STRING: + ap->a.a_string = va_arg (args, const char *); + /* A null pointer is an invalid argument for "%s", but in practice + it occurs quite frequently in printf statements that produce + debug output. Use a fallback in this case. */ + if (ap->a.a_string == NULL) + ap->a.a_string = "(NULL)"; + break; +#if HAVE_WCHAR_T + case TYPE_WIDE_STRING: + ap->a.a_wide_string = va_arg (args, const wchar_t *); + /* A null pointer is an invalid argument for "%ls", but in practice + it occurs quite frequently in printf statements that produce + debug output. Use a fallback in this case. */ + if (ap->a.a_wide_string == NULL) + { + static const wchar_t wide_null_string[] = + { + (wchar_t)'(', + (wchar_t)'N', (wchar_t)'U', (wchar_t)'L', (wchar_t)'L', + (wchar_t)')', + (wchar_t)0 + }; + ap->a.a_wide_string = wide_null_string; + } + break; +#endif + case TYPE_POINTER: + ap->a.a_pointer = va_arg (args, void *); + break; + case TYPE_COUNT_SCHAR_POINTER: + ap->a.a_count_schar_pointer = va_arg (args, signed char *); + break; + case TYPE_COUNT_SHORT_POINTER: + ap->a.a_count_short_pointer = va_arg (args, short *); + break; + case TYPE_COUNT_INT_POINTER: + ap->a.a_count_int_pointer = va_arg (args, int *); + break; + case TYPE_COUNT_LONGINT_POINTER: + ap->a.a_count_longint_pointer = va_arg (args, long int *); + break; +#if HAVE_LONG_LONG_INT + case TYPE_COUNT_LONGLONGINT_POINTER: + ap->a.a_count_longlongint_pointer = va_arg (args, long long int *); + break; +#endif +#if ENABLE_UNISTDIO + /* The unistdio extensions. */ + case TYPE_U8_STRING: + ap->a.a_u8_string = va_arg (args, const uint8_t *); + /* A null pointer is an invalid argument for "%U", but in practice + it occurs quite frequently in printf statements that produce + debug output. Use a fallback in this case. */ + if (ap->a.a_u8_string == NULL) + { + static const uint8_t u8_null_string[] = + { '(', 'N', 'U', 'L', 'L', ')', 0 }; + ap->a.a_u8_string = u8_null_string; + } + break; + case TYPE_U16_STRING: + ap->a.a_u16_string = va_arg (args, const uint16_t *); + /* A null pointer is an invalid argument for "%lU", but in practice + it occurs quite frequently in printf statements that produce + debug output. Use a fallback in this case. */ + if (ap->a.a_u16_string == NULL) + { + static const uint16_t u16_null_string[] = + { '(', 'N', 'U', 'L', 'L', ')', 0 }; + ap->a.a_u16_string = u16_null_string; + } + break; + case TYPE_U32_STRING: + ap->a.a_u32_string = va_arg (args, const uint32_t *); + /* A null pointer is an invalid argument for "%llU", but in practice + it occurs quite frequently in printf statements that produce + debug output. Use a fallback in this case. */ + if (ap->a.a_u32_string == NULL) + { + static const uint32_t u32_null_string[] = + { '(', 'N', 'U', 'L', 'L', ')', 0 }; + ap->a.a_u32_string = u32_null_string; + } + break; +#endif + default: + /* Unknown type. */ + return -1; + } + return 0; +} diff --git a/lib/printf-args.h b/lib/printf-args.h new file mode 100644 index 000000000..4c68f115f --- /dev/null +++ b/lib/printf-args.h @@ -0,0 +1,154 @@ +/* Decomposed printf argument list. + Copyright (C) 1999, 2002-2003, 2006-2007 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2, 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License along + with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef _PRINTF_ARGS_H +#define _PRINTF_ARGS_H + +/* This file can be parametrized with the following macros: + ENABLE_UNISTDIO Set to 1 to enable the unistdio extensions. + PRINTF_FETCHARGS Name of the function to be declared. + STATIC Set to 'static' to declare the function static. */ + +/* Default parameters. */ +#ifndef PRINTF_FETCHARGS +# define PRINTF_FETCHARGS printf_fetchargs +#endif + +/* Get size_t. */ +#include + +/* Get wchar_t. */ +#if HAVE_WCHAR_T +# include +#endif + +/* Get wint_t. */ +#if HAVE_WINT_T +# include +#endif + +/* Get va_list. */ +#include + + +/* Argument types */ +typedef enum +{ + TYPE_NONE, + TYPE_SCHAR, + TYPE_UCHAR, + TYPE_SHORT, + TYPE_USHORT, + TYPE_INT, + TYPE_UINT, + TYPE_LONGINT, + TYPE_ULONGINT, +#if HAVE_LONG_LONG_INT + TYPE_LONGLONGINT, + TYPE_ULONGLONGINT, +#endif + TYPE_DOUBLE, + TYPE_LONGDOUBLE, + TYPE_CHAR, +#if HAVE_WINT_T + TYPE_WIDE_CHAR, +#endif + TYPE_STRING, +#if HAVE_WCHAR_T + TYPE_WIDE_STRING, +#endif + TYPE_POINTER, + TYPE_COUNT_SCHAR_POINTER, + TYPE_COUNT_SHORT_POINTER, + TYPE_COUNT_INT_POINTER, + TYPE_COUNT_LONGINT_POINTER +#if HAVE_LONG_LONG_INT +, TYPE_COUNT_LONGLONGINT_POINTER +#endif +#if ENABLE_UNISTDIO + /* The unistdio extensions. */ +, TYPE_U8_STRING +, TYPE_U16_STRING +, TYPE_U32_STRING +#endif +} arg_type; + +/* Polymorphic argument */ +typedef struct +{ + arg_type type; + union + { + signed char a_schar; + unsigned char a_uchar; + short a_short; + unsigned short a_ushort; + int a_int; + unsigned int a_uint; + long int a_longint; + unsigned long int a_ulongint; +#if HAVE_LONG_LONG_INT + long long int a_longlongint; + unsigned long long int a_ulonglongint; +#endif + float a_float; + double a_double; + long double a_longdouble; + int a_char; +#if HAVE_WINT_T + wint_t a_wide_char; +#endif + const char* a_string; +#if HAVE_WCHAR_T + const wchar_t* a_wide_string; +#endif + void* a_pointer; + signed char * a_count_schar_pointer; + short * a_count_short_pointer; + int * a_count_int_pointer; + long int * a_count_longint_pointer; +#if HAVE_LONG_LONG_INT + long long int * a_count_longlongint_pointer; +#endif +#if ENABLE_UNISTDIO + /* The unistdio extensions. */ + const uint8_t * a_u8_string; + const uint16_t * a_u16_string; + const uint32_t * a_u32_string; +#endif + } + a; +} +argument; + +typedef struct +{ + size_t count; + argument *arg; +} +arguments; + + +/* Fetch the arguments, putting them into a. */ +#ifdef STATIC +STATIC +#else +extern +#endif +int PRINTF_FETCHARGS (va_list args, arguments *a); + +#endif /* _PRINTF_ARGS_H */ diff --git a/lib/printf-parse.c b/lib/printf-parse.c new file mode 100644 index 000000000..85c454b22 --- /dev/null +++ b/lib/printf-parse.c @@ -0,0 +1,627 @@ +/* Formatted output to strings. + Copyright (C) 1999-2000, 2002-2003, 2006-2008 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2, 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License along + with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* This file can be parametrized with the following macros: + CHAR_T The element type of the format string. + CHAR_T_ONLY_ASCII Set to 1 to enable verification that all characters + in the format string are ASCII. + DIRECTIVE Structure denoting a format directive. + Depends on CHAR_T. + DIRECTIVES Structure denoting the set of format directives of a + format string. Depends on CHAR_T. + PRINTF_PARSE Function that parses a format string. + Depends on CHAR_T. + STATIC Set to 'static' to declare the function static. + ENABLE_UNISTDIO Set to 1 to enable the unistdio extensions. */ + +#ifndef PRINTF_PARSE +# include +#endif + +/* Specification. */ +#ifndef PRINTF_PARSE +# include "printf-parse.h" +#endif + +/* Default parameters. */ +#ifndef PRINTF_PARSE +# define PRINTF_PARSE printf_parse +# define CHAR_T char +# define DIRECTIVE char_directive +# define DIRECTIVES char_directives +#endif + +/* Get size_t, NULL. */ +#include + +/* Get intmax_t. */ +#if defined IN_LIBINTL || defined IN_LIBASPRINTF +# if HAVE_STDINT_H_WITH_UINTMAX +# include +# endif +# if HAVE_INTTYPES_H_WITH_UINTMAX +# include +# endif +#else +# include +#endif + +/* malloc(), realloc(), free(). */ +#include + +/* errno. */ +#include + +/* Checked size_t computations. */ +#include "xsize.h" + +#if CHAR_T_ONLY_ASCII +/* c_isascii(). */ +# include "c-ctype.h" +#endif + +#ifdef STATIC +STATIC +#endif +int +PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a) +{ + const CHAR_T *cp = format; /* pointer into format */ + size_t arg_posn = 0; /* number of regular arguments consumed */ + size_t d_allocated; /* allocated elements of d->dir */ + size_t a_allocated; /* allocated elements of a->arg */ + size_t max_width_length = 0; + size_t max_precision_length = 0; + + d->count = 0; + d_allocated = 1; + d->dir = (DIRECTIVE *) malloc (d_allocated * sizeof (DIRECTIVE)); + if (d->dir == NULL) + /* Out of memory. */ + goto out_of_memory_1; + + a->count = 0; + a_allocated = 0; + a->arg = NULL; + +#define REGISTER_ARG(_index_,_type_) \ + { \ + size_t n = (_index_); \ + if (n >= a_allocated) \ + { \ + size_t memory_size; \ + argument *memory; \ + \ + a_allocated = xtimes (a_allocated, 2); \ + if (a_allocated <= n) \ + a_allocated = xsum (n, 1); \ + memory_size = xtimes (a_allocated, sizeof (argument)); \ + if (size_overflow_p (memory_size)) \ + /* Overflow, would lead to out of memory. */ \ + goto out_of_memory; \ + memory = (argument *) (a->arg \ + ? realloc (a->arg, memory_size) \ + : malloc (memory_size)); \ + if (memory == NULL) \ + /* Out of memory. */ \ + goto out_of_memory; \ + a->arg = memory; \ + } \ + while (a->count <= n) \ + a->arg[a->count++].type = TYPE_NONE; \ + if (a->arg[n].type == TYPE_NONE) \ + a->arg[n].type = (_type_); \ + else if (a->arg[n].type != (_type_)) \ + /* Ambiguous type for positional argument. */ \ + goto error; \ + } + + while (*cp != '\0') + { + CHAR_T c = *cp++; + if (c == '%') + { + size_t arg_index = ARG_NONE; + DIRECTIVE *dp = &d->dir[d->count]; /* pointer to next directive */ + + /* Initialize the next directive. */ + dp->dir_start = cp - 1; + dp->flags = 0; + dp->width_start = NULL; + dp->width_end = NULL; + dp->width_arg_index = ARG_NONE; + dp->precision_start = NULL; + dp->precision_end = NULL; + dp->precision_arg_index = ARG_NONE; + dp->arg_index = ARG_NONE; + + /* Test for positional argument. */ + if (*cp >= '0' && *cp <= '9') + { + const CHAR_T *np; + + for (np = cp; *np >= '0' && *np <= '9'; np++) + ; + if (*np == '$') + { + size_t n = 0; + + for (np = cp; *np >= '0' && *np <= '9'; np++) + n = xsum (xtimes (n, 10), *np - '0'); + if (n == 0) + /* Positional argument 0. */ + goto error; + if (size_overflow_p (n)) + /* n too large, would lead to out of memory later. */ + goto error; + arg_index = n - 1; + cp = np + 1; + } + } + + /* Read the flags. */ + for (;;) + { + if (*cp == '\'') + { + dp->flags |= FLAG_GROUP; + cp++; + } + else if (*cp == '-') + { + dp->flags |= FLAG_LEFT; + cp++; + } + else if (*cp == '+') + { + dp->flags |= FLAG_SHOWSIGN; + cp++; + } + else if (*cp == ' ') + { + dp->flags |= FLAG_SPACE; + cp++; + } + else if (*cp == '#') + { + dp->flags |= FLAG_ALT; + cp++; + } + else if (*cp == '0') + { + dp->flags |= FLAG_ZERO; + cp++; + } + else + break; + } + + /* Parse the field width. */ + if (*cp == '*') + { + dp->width_start = cp; + cp++; + dp->width_end = cp; + if (max_width_length < 1) + max_width_length = 1; + + /* Test for positional argument. */ + if (*cp >= '0' && *cp <= '9') + { + const CHAR_T *np; + + for (np = cp; *np >= '0' && *np <= '9'; np++) + ; + if (*np == '$') + { + size_t n = 0; + + for (np = cp; *np >= '0' && *np <= '9'; np++) + n = xsum (xtimes (n, 10), *np - '0'); + if (n == 0) + /* Positional argument 0. */ + goto error; + if (size_overflow_p (n)) + /* n too large, would lead to out of memory later. */ + goto error; + dp->width_arg_index = n - 1; + cp = np + 1; + } + } + if (dp->width_arg_index == ARG_NONE) + { + dp->width_arg_index = arg_posn++; + if (dp->width_arg_index == ARG_NONE) + /* arg_posn wrapped around. */ + goto error; + } + REGISTER_ARG (dp->width_arg_index, TYPE_INT); + } + else if (*cp >= '0' && *cp <= '9') + { + size_t width_length; + + dp->width_start = cp; + for (; *cp >= '0' && *cp <= '9'; cp++) + ; + dp->width_end = cp; + width_length = dp->width_end - dp->width_start; + if (max_width_length < width_length) + max_width_length = width_length; + } + + /* Parse the precision. */ + if (*cp == '.') + { + cp++; + if (*cp == '*') + { + dp->precision_start = cp - 1; + cp++; + dp->precision_end = cp; + if (max_precision_length < 2) + max_precision_length = 2; + + /* Test for positional argument. */ + if (*cp >= '0' && *cp <= '9') + { + const CHAR_T *np; + + for (np = cp; *np >= '0' && *np <= '9'; np++) + ; + if (*np == '$') + { + size_t n = 0; + + for (np = cp; *np >= '0' && *np <= '9'; np++) + n = xsum (xtimes (n, 10), *np - '0'); + if (n == 0) + /* Positional argument 0. */ + goto error; + if (size_overflow_p (n)) + /* n too large, would lead to out of memory + later. */ + goto error; + dp->precision_arg_index = n - 1; + cp = np + 1; + } + } + if (dp->precision_arg_index == ARG_NONE) + { + dp->precision_arg_index = arg_posn++; + if (dp->precision_arg_index == ARG_NONE) + /* arg_posn wrapped around. */ + goto error; + } + REGISTER_ARG (dp->precision_arg_index, TYPE_INT); + } + else + { + size_t precision_length; + + dp->precision_start = cp - 1; + for (; *cp >= '0' && *cp <= '9'; cp++) + ; + dp->precision_end = cp; + precision_length = dp->precision_end - dp->precision_start; + if (max_precision_length < precision_length) + max_precision_length = precision_length; + } + } + + { + arg_type type; + + /* Parse argument type/size specifiers. */ + { + int flags = 0; + + for (;;) + { + if (*cp == 'h') + { + flags |= (1 << (flags & 1)); + cp++; + } + else if (*cp == 'L') + { + flags |= 4; + cp++; + } + else if (*cp == 'l') + { + flags += 8; + cp++; + } + else if (*cp == 'j') + { + if (sizeof (intmax_t) > sizeof (long)) + { + /* intmax_t = long long */ + flags += 16; + } + else if (sizeof (intmax_t) > sizeof (int)) + { + /* intmax_t = long */ + flags += 8; + } + cp++; + } + else if (*cp == 'z' || *cp == 'Z') + { + /* 'z' is standardized in ISO C 99, but glibc uses 'Z' + because the warning facility in gcc-2.95.2 understands + only 'Z' (see gcc-2.95.2/gcc/c-common.c:1784). */ + if (sizeof (size_t) > sizeof (long)) + { + /* size_t = long long */ + flags += 16; + } + else if (sizeof (size_t) > sizeof (int)) + { + /* size_t = long */ + flags += 8; + } + cp++; + } + else if (*cp == 't') + { + if (sizeof (ptrdiff_t) > sizeof (long)) + { + /* ptrdiff_t = long long */ + flags += 16; + } + else if (sizeof (ptrdiff_t) > sizeof (int)) + { + /* ptrdiff_t = long */ + flags += 8; + } + cp++; + } +#if defined __APPLE__ && defined __MACH__ + /* On MacOS X 10.3, PRIdMAX is defined as "qd". + We cannot change it to "lld" because PRIdMAX must also + be understood by the system's printf routines. */ + else if (*cp == 'q') + { + if (64 / 8 > sizeof (long)) + { + /* int64_t = long long */ + flags += 16; + } + else + { + /* int64_t = long */ + flags += 8; + } + cp++; + } +#endif +#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ + /* On native Win32, PRIdMAX is defined as "I64d". + We cannot change it to "lld" because PRIdMAX must also + be understood by the system's printf routines. */ + else if (*cp == 'I' && cp[1] == '6' && cp[2] == '4') + { + if (64 / 8 > sizeof (long)) + { + /* __int64 = long long */ + flags += 16; + } + else + { + /* __int64 = long */ + flags += 8; + } + cp += 3; + } +#endif + else + break; + } + + /* Read the conversion character. */ + c = *cp++; + switch (c) + { + case 'd': case 'i': +#if HAVE_LONG_LONG_INT + /* If 'long long' exists and is larger than 'long': */ + if (flags >= 16 || (flags & 4)) + type = TYPE_LONGLONGINT; + else +#endif + /* If 'long long' exists and is the same as 'long', we parse + "lld" into TYPE_LONGINT. */ + if (flags >= 8) + type = TYPE_LONGINT; + else if (flags & 2) + type = TYPE_SCHAR; + else if (flags & 1) + type = TYPE_SHORT; + else + type = TYPE_INT; + break; + case 'o': case 'u': case 'x': case 'X': +#if HAVE_LONG_LONG_INT + /* If 'long long' exists and is larger than 'long': */ + if (flags >= 16 || (flags & 4)) + type = TYPE_ULONGLONGINT; + else +#endif + /* If 'unsigned long long' exists and is the same as + 'unsigned long', we parse "llu" into TYPE_ULONGINT. */ + if (flags >= 8) + type = TYPE_ULONGINT; + else if (flags & 2) + type = TYPE_UCHAR; + else if (flags & 1) + type = TYPE_USHORT; + else + type = TYPE_UINT; + break; + case 'f': case 'F': case 'e': case 'E': case 'g': case 'G': + case 'a': case 'A': + if (flags >= 16 || (flags & 4)) + type = TYPE_LONGDOUBLE; + else + type = TYPE_DOUBLE; + break; + case 'c': + if (flags >= 8) +#if HAVE_WINT_T + type = TYPE_WIDE_CHAR; +#else + goto error; +#endif + else + type = TYPE_CHAR; + break; +#if HAVE_WINT_T + case 'C': + type = TYPE_WIDE_CHAR; + c = 'c'; + break; +#endif + case 's': + if (flags >= 8) +#if HAVE_WCHAR_T + type = TYPE_WIDE_STRING; +#else + goto error; +#endif + else + type = TYPE_STRING; + break; +#if HAVE_WCHAR_T + case 'S': + type = TYPE_WIDE_STRING; + c = 's'; + break; +#endif + case 'p': + type = TYPE_POINTER; + break; + case 'n': +#if HAVE_LONG_LONG_INT + /* If 'long long' exists and is larger than 'long': */ + if (flags >= 16 || (flags & 4)) + type = TYPE_COUNT_LONGLONGINT_POINTER; + else +#endif + /* If 'long long' exists and is the same as 'long', we parse + "lln" into TYPE_COUNT_LONGINT_POINTER. */ + if (flags >= 8) + type = TYPE_COUNT_LONGINT_POINTER; + else if (flags & 2) + type = TYPE_COUNT_SCHAR_POINTER; + else if (flags & 1) + type = TYPE_COUNT_SHORT_POINTER; + else + type = TYPE_COUNT_INT_POINTER; + break; +#if ENABLE_UNISTDIO + /* The unistdio extensions. */ + case 'U': + if (flags >= 16) + type = TYPE_U32_STRING; + else if (flags >= 8) + type = TYPE_U16_STRING; + else + type = TYPE_U8_STRING; + break; +#endif + case '%': + type = TYPE_NONE; + break; + default: + /* Unknown conversion character. */ + goto error; + } + } + + if (type != TYPE_NONE) + { + dp->arg_index = arg_index; + if (dp->arg_index == ARG_NONE) + { + dp->arg_index = arg_posn++; + if (dp->arg_index == ARG_NONE) + /* arg_posn wrapped around. */ + goto error; + } + REGISTER_ARG (dp->arg_index, type); + } + dp->conversion = c; + dp->dir_end = cp; + } + + d->count++; + if (d->count >= d_allocated) + { + size_t memory_size; + DIRECTIVE *memory; + + d_allocated = xtimes (d_allocated, 2); + memory_size = xtimes (d_allocated, sizeof (DIRECTIVE)); + if (size_overflow_p (memory_size)) + /* Overflow, would lead to out of memory. */ + goto out_of_memory; + memory = (DIRECTIVE *) realloc (d->dir, memory_size); + if (memory == NULL) + /* Out of memory. */ + goto out_of_memory; + d->dir = memory; + } + } +#if CHAR_T_ONLY_ASCII + else if (!c_isascii (c)) + { + /* Non-ASCII character. Not supported. */ + goto error; + } +#endif + } + d->dir[d->count].dir_start = cp; + + d->max_width_length = max_width_length; + d->max_precision_length = max_precision_length; + return 0; + +error: + if (a->arg) + free (a->arg); + if (d->dir) + free (d->dir); + errno = EINVAL; + return -1; + +out_of_memory: + if (a->arg) + free (a->arg); + if (d->dir) + free (d->dir); +out_of_memory_1: + errno = ENOMEM; + return -1; +} + +#undef PRINTF_PARSE +#undef DIRECTIVES +#undef DIRECTIVE +#undef CHAR_T_ONLY_ASCII +#undef CHAR_T diff --git a/lib/printf-parse.h b/lib/printf-parse.h new file mode 100644 index 000000000..0a496cbda --- /dev/null +++ b/lib/printf-parse.h @@ -0,0 +1,179 @@ +/* Parse printf format string. + Copyright (C) 1999, 2002-2003, 2005, 2007 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2, 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License along + with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef _PRINTF_PARSE_H +#define _PRINTF_PARSE_H + +/* This file can be parametrized with the following macros: + ENABLE_UNISTDIO Set to 1 to enable the unistdio extensions. + STATIC Set to 'static' to declare the function static. */ + +#include "printf-args.h" + + +/* Flags */ +#define FLAG_GROUP 1 /* ' flag */ +#define FLAG_LEFT 2 /* - flag */ +#define FLAG_SHOWSIGN 4 /* + flag */ +#define FLAG_SPACE 8 /* space flag */ +#define FLAG_ALT 16 /* # flag */ +#define FLAG_ZERO 32 + +/* arg_index value indicating that no argument is consumed. */ +#define ARG_NONE (~(size_t)0) + +/* xxx_directive: A parsed directive. + xxx_directives: A parsed format string. */ + +/* A parsed directive. */ +typedef struct +{ + const char* dir_start; + const char* dir_end; + int flags; + const char* width_start; + const char* width_end; + size_t width_arg_index; + const char* precision_start; + const char* precision_end; + size_t precision_arg_index; + char conversion; /* d i o u x X f F e E g G a A c s p n U % but not C S */ + size_t arg_index; +} +char_directive; + +/* A parsed format string. */ +typedef struct +{ + size_t count; + char_directive *dir; + size_t max_width_length; + size_t max_precision_length; +} +char_directives; + +#if ENABLE_UNISTDIO + +/* A parsed directive. */ +typedef struct +{ + const uint8_t* dir_start; + const uint8_t* dir_end; + int flags; + const uint8_t* width_start; + const uint8_t* width_end; + size_t width_arg_index; + const uint8_t* precision_start; + const uint8_t* precision_end; + size_t precision_arg_index; + uint8_t conversion; /* d i o u x X f F e E g G a A c s p n U % but not C S */ + size_t arg_index; +} +u8_directive; + +/* A parsed format string. */ +typedef struct +{ + size_t count; + u8_directive *dir; + size_t max_width_length; + size_t max_precision_length; +} +u8_directives; + +/* A parsed directive. */ +typedef struct +{ + const uint16_t* dir_start; + const uint16_t* dir_end; + int flags; + const uint16_t* width_start; + const uint16_t* width_end; + size_t width_arg_index; + const uint16_t* precision_start; + const uint16_t* precision_end; + size_t precision_arg_index; + uint16_t conversion; /* d i o u x X f F e E g G a A c s p n U % but not C S */ + size_t arg_index; +} +u16_directive; + +/* A parsed format string. */ +typedef struct +{ + size_t count; + u16_directive *dir; + size_t max_width_length; + size_t max_precision_length; +} +u16_directives; + +/* A parsed directive. */ +typedef struct +{ + const uint32_t* dir_start; + const uint32_t* dir_end; + int flags; + const uint32_t* width_start; + const uint32_t* width_end; + size_t width_arg_index; + const uint32_t* precision_start; + const uint32_t* precision_end; + size_t precision_arg_index; + uint32_t conversion; /* d i o u x X f F e E g G a A c s p n U % but not C S */ + size_t arg_index; +} +u32_directive; + +/* A parsed format string. */ +typedef struct +{ + size_t count; + u32_directive *dir; + size_t max_width_length; + size_t max_precision_length; +} +u32_directives; + +#endif + + +/* Parses the format string. Fills in the number N of directives, and fills + in directives[0], ..., directives[N-1], and sets directives[N].dir_start + to the end of the format string. Also fills in the arg_type fields of the + arguments and the needed count of arguments. */ +#if ENABLE_UNISTDIO +extern int + ulc_printf_parse (const char *format, char_directives *d, arguments *a); +extern int + u8_printf_parse (const uint8_t *format, u8_directives *d, arguments *a); +extern int + u16_printf_parse (const uint16_t *format, u16_directives *d, + arguments *a); +extern int + u32_printf_parse (const uint32_t *format, u32_directives *d, + arguments *a); +#else +# ifdef STATIC +STATIC +# else +extern +# endif +int printf_parse (const char *format, char_directives *d, arguments *a); +#endif + +#endif /* _PRINTF_PARSE_H */ diff --git a/lib/putenv.c b/lib/putenv.c new file mode 100644 index 000000000..53cc83912 --- /dev/null +++ b/lib/putenv.c @@ -0,0 +1,132 @@ +/* Copyright (C) 1991, 1994, 1997-1998, 2000, 2003-2008 + Free Software Foundation, Inc. + + NOTE: The canonical source of this file is maintained with the GNU C + Library. Bugs can be reported to bug-glibc@prep.ai.mit.edu. + + This program is free software: you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by the + Free Software Foundation; either version 3 of the License, or 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#include + +/* Specification. */ +#include + +#include + +/* Include errno.h *after* sys/types.h to work around header problems + on AIX 3.2.5. */ +#include +#ifndef __set_errno +# define __set_errno(ev) ((errno) = (ev)) +#endif + +#include +#include + +#if HAVE_GNU_LD +# define environ __environ +#else +extern char **environ; +#endif + +#if _LIBC +/* This lock protects against simultaneous modifications of `environ'. */ +# include +__libc_lock_define_initialized (static, envlock) +# define LOCK __libc_lock_lock (envlock) +# define UNLOCK __libc_lock_unlock (envlock) +#else +# define LOCK +# define UNLOCK +#endif + +static int +_unsetenv (const char *name) +{ + size_t len; + char **ep; + + if (name == NULL || *name == '\0' || strchr (name, '=') != NULL) + { + __set_errno (EINVAL); + return -1; + } + + len = strlen (name); + + LOCK; + + ep = environ; + while (*ep != NULL) + if (!strncmp (*ep, name, len) && (*ep)[len] == '=') + { + /* Found it. Remove this pointer by moving later ones back. */ + char **dp = ep; + + do + dp[0] = dp[1]; + while (*dp++); + /* Continue the loop in case NAME appears again. */ + } + else + ++ep; + + UNLOCK; + + return 0; +} + + +/* Put STRING, which is of the form "NAME=VALUE", in the environment. + If STRING contains no `=', then remove STRING from the environment. */ +int +putenv (char *string) +{ + const char *const name_end = strchr (string, '='); + register size_t size; + register char **ep; + + if (name_end == NULL) + { + /* Remove the variable from the environment. */ + return _unsetenv (string); + } + + size = 0; + for (ep = environ; *ep != NULL; ++ep) + if (!strncmp (*ep, string, name_end - string) && + (*ep)[name_end - string] == '=') + break; + else + ++size; + + if (*ep == NULL) + { + static char **last_environ = NULL; + char **new_environ = (char **) malloc ((size + 2) * sizeof (char *)); + if (new_environ == NULL) + return -1; + (void) memcpy ((void *) new_environ, (void *) environ, + size * sizeof (char *)); + new_environ[size] = (char *) string; + new_environ[size + 1] = NULL; + free (last_environ); + last_environ = new_environ; + environ = new_environ; + } + else + *ep = string; + + return 0; +} diff --git a/lib/readlink.c b/lib/readlink.c new file mode 100644 index 000000000..c9f49f815 --- /dev/null +++ b/lib/readlink.c @@ -0,0 +1,49 @@ +/* Stub for readlink(). + Copyright (C) 2003-2007 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#include + +/* Specification. */ +#include + +#include +#include +#include +#include + +#if !HAVE_READLINK + +/* readlink() substitute for systems that don't have a readlink() function, + such as DJGPP 2.03 and mingw32. */ + +/* The official POSIX return type of readlink() is ssize_t, but since here + we have no declaration in a public header file, we use 'int' as return + type. */ + +int +readlink (const char *path, char *buf, size_t bufsize) +{ + struct stat statbuf; + + /* In general we should use lstat() here, not stat(). But on platforms + without symbolic links lstat() - if it exists - would be equivalent to + stat(), therefore we can use stat(). This saves us a configure check. */ + if (stat (path, &statbuf) >= 0) + errno = EINVAL; + return -1; +} + +#endif diff --git a/lib/size_max.h b/lib/size_max.h new file mode 100644 index 000000000..419d73a18 --- /dev/null +++ b/lib/size_max.h @@ -0,0 +1,31 @@ +/* size_max.h -- declare SIZE_MAX through system headers + Copyright (C) 2005-2006 Free Software Foundation, Inc. + Written by Simon Josefsson. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2, 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef GNULIB_SIZE_MAX_H +#define GNULIB_SIZE_MAX_H + +/* Get SIZE_MAX declaration on systems like Solaris 7/8/9. */ +# include +/* Get SIZE_MAX declaration on systems like glibc 2. */ +# if HAVE_STDINT_H +# include +# endif +/* On systems where these include files don't define it, SIZE_MAX is defined + in config.h. */ + +#endif /* GNULIB_SIZE_MAX_H */ diff --git a/lib/stdint.in.h b/lib/stdint.in.h new file mode 100644 index 000000000..11a211763 --- /dev/null +++ b/lib/stdint.in.h @@ -0,0 +1,567 @@ +/* Copyright (C) 2001-2002, 2004-2009 Free Software Foundation, Inc. + Written by Paul Eggert, Bruno Haible, Sam Steingold, Peter Burwood. + This file is part of gnulib. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2, 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* + * ISO C 99 for platforms that lack it. + * + */ + +#ifndef _GL_STDINT_H + +/* When including a system file that in turn includes , + use the system , not our substitute. This avoids + problems with (for example) VMS, whose includes + . */ +#define _GL_JUST_INCLUDE_SYSTEM_INTTYPES_H + +/* Get those types that are already defined in other system include + files, so that we can "#define int8_t signed char" below without + worrying about a later system include file containing a "typedef + signed char int8_t;" that will get messed up by our macro. Our + macros should all be consistent with the system versions, except + for the "fast" types and macros, which we recommend against using + in public interfaces due to compiler differences. */ + +#if @HAVE_STDINT_H@ +# if defined __sgi && ! defined __c99 + /* Bypass IRIX's if in C89 mode, since it merely annoys users + with "This header file is to be used only for c99 mode compilations" + diagnostics. */ +# define __STDINT_H__ +# endif + /* Other systems may have an incomplete or buggy . + Include it before , since any "#include " + in would reinclude us, skipping our contents because + _GL_STDINT_H is defined. + The include_next requires a split double-inclusion guard. */ +# if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +# endif +# @INCLUDE_NEXT@ @NEXT_STDINT_H@ +#endif + +#if ! defined _GL_STDINT_H && ! defined _GL_JUST_INCLUDE_SYSTEM_STDINT_H +#define _GL_STDINT_H + +/* defines some of the stdint.h types as well, on glibc, + IRIX 6.5, and OpenBSD 3.8 (via ). + AIX 5.2 isn't needed and causes troubles. + MacOS X 10.4.6 includes (which is us), but + relies on the system definitions, so include + after @NEXT_STDINT_H@. */ +#if @HAVE_SYS_TYPES_H@ && ! defined _AIX +# include +#endif + +/* Get LONG_MIN, LONG_MAX, ULONG_MAX. */ +#include + +#if @HAVE_INTTYPES_H@ + /* In OpenBSD 3.8, includes , which defines + int{8,16,32,64}_t, uint{8,16,32,64}_t and __BIT_TYPES_DEFINED__. + also defines intptr_t and uintptr_t. */ +# include +#elif @HAVE_SYS_INTTYPES_H@ + /* Solaris 7 has the types except the *_fast*_t types, and + the macros except for *_FAST*_*, INTPTR_MIN, PTRDIFF_MIN, PTRDIFF_MAX. */ +# include +#endif + +#if @HAVE_SYS_BITYPES_H@ && ! defined __BIT_TYPES_DEFINED__ + /* Linux libc4 >= 4.6.7 and libc5 have a that defines + int{8,16,32,64}_t and __BIT_TYPES_DEFINED__. In libc5 >= 5.2.2 it is + included by . */ +# include +#endif + +#undef _GL_JUST_INCLUDE_SYSTEM_INTTYPES_H + +/* Minimum and maximum values for a integer type under the usual assumption. + Return an unspecified value if BITS == 0, adding a check to pacify + picky compilers. */ + +#define _STDINT_MIN(signed, bits, zero) \ + ((signed) ? (- ((zero) + 1) << ((bits) ? (bits) - 1 : 0)) : (zero)) + +#define _STDINT_MAX(signed, bits, zero) \ + ((signed) \ + ? ~ _STDINT_MIN (signed, bits, zero) \ + : /* The expression for the unsigned case. The subtraction of (signed) \ + is a nop in the unsigned case and avoids "signed integer overflow" \ + warnings in the signed case. */ \ + ((((zero) + 1) << ((bits) ? (bits) - 1 - (signed) : 0)) - 1) * 2 + 1) + +/* 7.18.1.1. Exact-width integer types */ + +/* Here we assume a standard architecture where the hardware integer + types have 8, 16, 32, optionally 64 bits. */ + +#undef int8_t +#undef uint8_t +typedef signed char gl_int8_t; +typedef unsigned char gl_uint8_t; +#define int8_t gl_int8_t +#define uint8_t gl_uint8_t + +#undef int16_t +#undef uint16_t +typedef short int gl_int16_t; +typedef unsigned short int gl_uint16_t; +#define int16_t gl_int16_t +#define uint16_t gl_uint16_t + +#undef int32_t +#undef uint32_t +typedef int gl_int32_t; +typedef unsigned int gl_uint32_t; +#define int32_t gl_int32_t +#define uint32_t gl_uint32_t + +/* Do not undefine int64_t if gnulib is not being used with 64-bit + types, since otherwise it breaks platforms like Tandem/NSK. */ +#if LONG_MAX >> 31 >> 31 == 1 +# undef int64_t +typedef long int gl_int64_t; +# define int64_t gl_int64_t +# define GL_INT64_T +#elif defined _MSC_VER +# undef int64_t +typedef __int64 gl_int64_t; +# define int64_t gl_int64_t +# define GL_INT64_T +#elif @HAVE_LONG_LONG_INT@ +# undef int64_t +typedef long long int gl_int64_t; +# define int64_t gl_int64_t +# define GL_INT64_T +#endif + +#if ULONG_MAX >> 31 >> 31 >> 1 == 1 +# undef uint64_t +typedef unsigned long int gl_uint64_t; +# define uint64_t gl_uint64_t +# define GL_UINT64_T +#elif defined _MSC_VER +# undef uint64_t +typedef unsigned __int64 gl_uint64_t; +# define uint64_t gl_uint64_t +# define GL_UINT64_T +#elif @HAVE_UNSIGNED_LONG_LONG_INT@ +# undef uint64_t +typedef unsigned long long int gl_uint64_t; +# define uint64_t gl_uint64_t +# define GL_UINT64_T +#endif + +/* Avoid collision with Solaris 2.5.1 etc. */ +#define _UINT8_T +#define _UINT32_T +#define _UINT64_T + + +/* 7.18.1.2. Minimum-width integer types */ + +/* Here we assume a standard architecture where the hardware integer + types have 8, 16, 32, optionally 64 bits. Therefore the leastN_t types + are the same as the corresponding N_t types. */ + +#undef int_least8_t +#undef uint_least8_t +#undef int_least16_t +#undef uint_least16_t +#undef int_least32_t +#undef uint_least32_t +#undef int_least64_t +#undef uint_least64_t +#define int_least8_t int8_t +#define uint_least8_t uint8_t +#define int_least16_t int16_t +#define uint_least16_t uint16_t +#define int_least32_t int32_t +#define uint_least32_t uint32_t +#ifdef GL_INT64_T +# define int_least64_t int64_t +#endif +#ifdef GL_UINT64_T +# define uint_least64_t uint64_t +#endif + +/* 7.18.1.3. Fastest minimum-width integer types */ + +/* Note: Other substitutes may define these types differently. + It is not recommended to use these types in public header files. */ + +/* Here we assume a standard architecture where the hardware integer + types have 8, 16, 32, optionally 64 bits. Therefore the fastN_t types + are taken from the same list of types. Assume that 'long int' + is fast enough for all narrower integers. */ + +#undef int_fast8_t +#undef uint_fast8_t +#undef int_fast16_t +#undef uint_fast16_t +#undef int_fast32_t +#undef uint_fast32_t +#undef int_fast64_t +#undef uint_fast64_t +typedef long int gl_int_fast8_t; +typedef unsigned long int gl_uint_fast8_t; +typedef long int gl_int_fast16_t; +typedef unsigned long int gl_uint_fast16_t; +typedef long int gl_int_fast32_t; +typedef unsigned long int gl_uint_fast32_t; +#define int_fast8_t gl_int_fast8_t +#define uint_fast8_t gl_uint_fast8_t +#define int_fast16_t gl_int_fast16_t +#define uint_fast16_t gl_uint_fast16_t +#define int_fast32_t gl_int_fast32_t +#define uint_fast32_t gl_uint_fast32_t +#ifdef GL_INT64_T +# define int_fast64_t int64_t +#endif +#ifdef GL_UINT64_T +# define uint_fast64_t uint64_t +#endif + +/* 7.18.1.4. Integer types capable of holding object pointers */ + +#undef intptr_t +#undef uintptr_t +typedef long int gl_intptr_t; +typedef unsigned long int gl_uintptr_t; +#define intptr_t gl_intptr_t +#define uintptr_t gl_uintptr_t + +/* 7.18.1.5. Greatest-width integer types */ + +/* Note: These types are compiler dependent. It may be unwise to use them in + public header files. */ + +#undef intmax_t +#if @HAVE_LONG_LONG_INT@ && LONG_MAX >> 30 == 1 +typedef long long int gl_intmax_t; +# define intmax_t gl_intmax_t +#elif defined GL_INT64_T +# define intmax_t int64_t +#else +typedef long int gl_intmax_t; +# define intmax_t gl_intmax_t +#endif + +#undef uintmax_t +#if @HAVE_UNSIGNED_LONG_LONG_INT@ && ULONG_MAX >> 31 == 1 +typedef unsigned long long int gl_uintmax_t; +# define uintmax_t gl_uintmax_t +#elif defined GL_UINT64_T +# define uintmax_t uint64_t +#else +typedef unsigned long int gl_uintmax_t; +# define uintmax_t gl_uintmax_t +#endif + +/* Verify that intmax_t and uintmax_t have the same size. Too much code + breaks if this is not the case. If this check fails, the reason is likely + to be found in the autoconf macros. */ +typedef int _verify_intmax_size[2 * (sizeof (intmax_t) == sizeof (uintmax_t)) - 1]; + +/* 7.18.2. Limits of specified-width integer types */ + +#if ! defined __cplusplus || defined __STDC_LIMIT_MACROS + +/* 7.18.2.1. Limits of exact-width integer types */ + +/* Here we assume a standard architecture where the hardware integer + types have 8, 16, 32, optionally 64 bits. */ + +#undef INT8_MIN +#undef INT8_MAX +#undef UINT8_MAX +#define INT8_MIN (~ INT8_MAX) +#define INT8_MAX 127 +#define UINT8_MAX 255 + +#undef INT16_MIN +#undef INT16_MAX +#undef UINT16_MAX +#define INT16_MIN (~ INT16_MAX) +#define INT16_MAX 32767 +#define UINT16_MAX 65535 + +#undef INT32_MIN +#undef INT32_MAX +#undef UINT32_MAX +#define INT32_MIN (~ INT32_MAX) +#define INT32_MAX 2147483647 +#define UINT32_MAX 4294967295U + +#undef INT64_MIN +#undef INT64_MAX +#ifdef GL_INT64_T +/* Prefer (- INTMAX_C (1) << 63) over (~ INT64_MAX) because SunPRO C 5.0 + evaluates the latter incorrectly in preprocessor expressions. */ +# define INT64_MIN (- INTMAX_C (1) << 63) +# define INT64_MAX INTMAX_C (9223372036854775807) +#endif + +#undef UINT64_MAX +#ifdef GL_UINT64_T +# define UINT64_MAX UINTMAX_C (18446744073709551615) +#endif + +/* 7.18.2.2. Limits of minimum-width integer types */ + +/* Here we assume a standard architecture where the hardware integer + types have 8, 16, 32, optionally 64 bits. Therefore the leastN_t types + are the same as the corresponding N_t types. */ + +#undef INT_LEAST8_MIN +#undef INT_LEAST8_MAX +#undef UINT_LEAST8_MAX +#define INT_LEAST8_MIN INT8_MIN +#define INT_LEAST8_MAX INT8_MAX +#define UINT_LEAST8_MAX UINT8_MAX + +#undef INT_LEAST16_MIN +#undef INT_LEAST16_MAX +#undef UINT_LEAST16_MAX +#define INT_LEAST16_MIN INT16_MIN +#define INT_LEAST16_MAX INT16_MAX +#define UINT_LEAST16_MAX UINT16_MAX + +#undef INT_LEAST32_MIN +#undef INT_LEAST32_MAX +#undef UINT_LEAST32_MAX +#define INT_LEAST32_MIN INT32_MIN +#define INT_LEAST32_MAX INT32_MAX +#define UINT_LEAST32_MAX UINT32_MAX + +#undef INT_LEAST64_MIN +#undef INT_LEAST64_MAX +#ifdef GL_INT64_T +# define INT_LEAST64_MIN INT64_MIN +# define INT_LEAST64_MAX INT64_MAX +#endif + +#undef UINT_LEAST64_MAX +#ifdef GL_UINT64_T +# define UINT_LEAST64_MAX UINT64_MAX +#endif + +/* 7.18.2.3. Limits of fastest minimum-width integer types */ + +/* Here we assume a standard architecture where the hardware integer + types have 8, 16, 32, optionally 64 bits. Therefore the fastN_t types + are taken from the same list of types. */ + +#undef INT_FAST8_MIN +#undef INT_FAST8_MAX +#undef UINT_FAST8_MAX +#define INT_FAST8_MIN LONG_MIN +#define INT_FAST8_MAX LONG_MAX +#define UINT_FAST8_MAX ULONG_MAX + +#undef INT_FAST16_MIN +#undef INT_FAST16_MAX +#undef UINT_FAST16_MAX +#define INT_FAST16_MIN LONG_MIN +#define INT_FAST16_MAX LONG_MAX +#define UINT_FAST16_MAX ULONG_MAX + +#undef INT_FAST32_MIN +#undef INT_FAST32_MAX +#undef UINT_FAST32_MAX +#define INT_FAST32_MIN LONG_MIN +#define INT_FAST32_MAX LONG_MAX +#define UINT_FAST32_MAX ULONG_MAX + +#undef INT_FAST64_MIN +#undef INT_FAST64_MAX +#ifdef GL_INT64_T +# define INT_FAST64_MIN INT64_MIN +# define INT_FAST64_MAX INT64_MAX +#endif + +#undef UINT_FAST64_MAX +#ifdef GL_UINT64_T +# define UINT_FAST64_MAX UINT64_MAX +#endif + +/* 7.18.2.4. Limits of integer types capable of holding object pointers */ + +#undef INTPTR_MIN +#undef INTPTR_MAX +#undef UINTPTR_MAX +#define INTPTR_MIN LONG_MIN +#define INTPTR_MAX LONG_MAX +#define UINTPTR_MAX ULONG_MAX + +/* 7.18.2.5. Limits of greatest-width integer types */ + +#undef INTMAX_MIN +#undef INTMAX_MAX +#ifdef INT64_MAX +# define INTMAX_MIN INT64_MIN +# define INTMAX_MAX INT64_MAX +#else +# define INTMAX_MIN INT32_MIN +# define INTMAX_MAX INT32_MAX +#endif + +#undef UINTMAX_MAX +#ifdef UINT64_MAX +# define UINTMAX_MAX UINT64_MAX +#else +# define UINTMAX_MAX UINT32_MAX +#endif + +/* 7.18.3. Limits of other integer types */ + +/* ptrdiff_t limits */ +#undef PTRDIFF_MIN +#undef PTRDIFF_MAX +#if @APPLE_UNIVERSAL_BUILD@ +# ifdef _LP64 +# define PTRDIFF_MIN _STDINT_MIN (1, 64, 0l) +# define PTRDIFF_MAX _STDINT_MAX (1, 64, 0l) +# else +# define PTRDIFF_MIN _STDINT_MIN (1, 32, 0) +# define PTRDIFF_MAX _STDINT_MAX (1, 32, 0) +# endif +#else +# define PTRDIFF_MIN \ + _STDINT_MIN (1, @BITSIZEOF_PTRDIFF_T@, 0@PTRDIFF_T_SUFFIX@) +# define PTRDIFF_MAX \ + _STDINT_MAX (1, @BITSIZEOF_PTRDIFF_T@, 0@PTRDIFF_T_SUFFIX@) +#endif + +/* sig_atomic_t limits */ +#undef SIG_ATOMIC_MIN +#undef SIG_ATOMIC_MAX +#define SIG_ATOMIC_MIN \ + _STDINT_MIN (@HAVE_SIGNED_SIG_ATOMIC_T@, @BITSIZEOF_SIG_ATOMIC_T@, \ + 0@SIG_ATOMIC_T_SUFFIX@) +#define SIG_ATOMIC_MAX \ + _STDINT_MAX (@HAVE_SIGNED_SIG_ATOMIC_T@, @BITSIZEOF_SIG_ATOMIC_T@, \ + 0@SIG_ATOMIC_T_SUFFIX@) + + +/* size_t limit */ +#undef SIZE_MAX +#if @APPLE_UNIVERSAL_BUILD@ +# ifdef _LP64 +# define SIZE_MAX _STDINT_MAX (0, 64, 0ul) +# else +# define SIZE_MAX _STDINT_MAX (0, 32, 0ul) +# endif +#else +# define SIZE_MAX _STDINT_MAX (0, @BITSIZEOF_SIZE_T@, 0@SIZE_T_SUFFIX@) +#endif + +/* wchar_t limits */ +/* Get WCHAR_MIN, WCHAR_MAX. + This include is not on the top, above, because on OSF/1 4.0 we have a sequence of nested + includes -> -> -> , and the latter includes + and assumes its types are already defined. */ +#if ! (defined WCHAR_MIN && defined WCHAR_MAX) +# define _GL_JUST_INCLUDE_SYSTEM_WCHAR_H +# include +# undef _GL_JUST_INCLUDE_SYSTEM_WCHAR_H +#endif +#undef WCHAR_MIN +#undef WCHAR_MAX +#define WCHAR_MIN \ + _STDINT_MIN (@HAVE_SIGNED_WCHAR_T@, @BITSIZEOF_WCHAR_T@, 0@WCHAR_T_SUFFIX@) +#define WCHAR_MAX \ + _STDINT_MAX (@HAVE_SIGNED_WCHAR_T@, @BITSIZEOF_WCHAR_T@, 0@WCHAR_T_SUFFIX@) + +/* wint_t limits */ +#undef WINT_MIN +#undef WINT_MAX +#define WINT_MIN \ + _STDINT_MIN (@HAVE_SIGNED_WINT_T@, @BITSIZEOF_WINT_T@, 0@WINT_T_SUFFIX@) +#define WINT_MAX \ + _STDINT_MAX (@HAVE_SIGNED_WINT_T@, @BITSIZEOF_WINT_T@, 0@WINT_T_SUFFIX@) + +#endif /* !defined __cplusplus || defined __STDC_LIMIT_MACROS */ + +/* 7.18.4. Macros for integer constants */ + +#if ! defined __cplusplus || defined __STDC_CONSTANT_MACROS + +/* 7.18.4.1. Macros for minimum-width integer constants */ +/* According to ISO C 99 Technical Corrigendum 1 */ + +/* Here we assume a standard architecture where the hardware integer + types have 8, 16, 32, optionally 64 bits, and int is 32 bits. */ + +#undef INT8_C +#undef UINT8_C +#define INT8_C(x) x +#define UINT8_C(x) x + +#undef INT16_C +#undef UINT16_C +#define INT16_C(x) x +#define UINT16_C(x) x + +#undef INT32_C +#undef UINT32_C +#define INT32_C(x) x +#define UINT32_C(x) x ## U + +#undef INT64_C +#undef UINT64_C +#if LONG_MAX >> 31 >> 31 == 1 +# define INT64_C(x) x##L +#elif defined _MSC_VER +# define INT64_C(x) x##i64 +#elif @HAVE_LONG_LONG_INT@ +# define INT64_C(x) x##LL +#endif +#if ULONG_MAX >> 31 >> 31 >> 1 == 1 +# define UINT64_C(x) x##UL +#elif defined _MSC_VER +# define UINT64_C(x) x##ui64 +#elif @HAVE_UNSIGNED_LONG_LONG_INT@ +# define UINT64_C(x) x##ULL +#endif + +/* 7.18.4.2. Macros for greatest-width integer constants */ + +#undef INTMAX_C +#if @HAVE_LONG_LONG_INT@ && LONG_MAX >> 30 == 1 +# define INTMAX_C(x) x##LL +#elif defined GL_INT64_T +# define INTMAX_C(x) INT64_C(x) +#else +# define INTMAX_C(x) x##L +#endif + +#undef UINTMAX_C +#if @HAVE_UNSIGNED_LONG_LONG_INT@ && ULONG_MAX >> 31 == 1 +# define UINTMAX_C(x) x##ULL +#elif defined GL_UINT64_T +# define UINTMAX_C(x) UINT64_C(x) +#else +# define UINTMAX_C(x) x##UL +#endif + +#endif /* !defined __cplusplus || defined __STDC_CONSTANT_MACROS */ + +#endif /* _GL_STDINT_H */ +#endif /* !defined _GL_STDINT_H && !defined _GL_JUST_INCLUDE_SYSTEM_STDINT_H */ diff --git a/lib/stdio-write.c b/lib/stdio-write.c new file mode 100644 index 000000000..8f275ffb2 --- /dev/null +++ b/lib/stdio-write.c @@ -0,0 +1,148 @@ +/* POSIX compatible FILE stream write function. + Copyright (C) 2008 Free Software Foundation, Inc. + Written by Bruno Haible , 2008. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#include + +/* Specification. */ +#include + +/* Replace these functions only if module 'sigpipe' is requested. */ +#if GNULIB_SIGPIPE + +/* On native Windows platforms, SIGPIPE does not exist. When write() is + called on a pipe with no readers, WriteFile() fails with error + GetLastError() = ERROR_NO_DATA, and write() in consequence fails with + error EINVAL. This write() function is at the basis of the function + which flushes the buffer of a FILE stream. */ + +# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ + +# include +# include +# include + +# define WIN32_LEAN_AND_MEAN /* avoid including junk */ +# include + +# define CALL_WITH_SIGPIPE_EMULATION(RETTYPE, EXPRESSION, FAILED) \ + if (ferror (stream)) \ + return (EXPRESSION); \ + else \ + { \ + RETTYPE ret; \ + SetLastError (0); \ + ret = (EXPRESSION); \ + if (FAILED && GetLastError () == ERROR_NO_DATA && ferror (stream)) \ + { \ + int fd = fileno (stream); \ + if (fd >= 0 \ + && GetFileType ((HANDLE) _get_osfhandle (fd)) == FILE_TYPE_PIPE)\ + { \ + /* Try to raise signal SIGPIPE. */ \ + raise (SIGPIPE); \ + /* If it is currently blocked or ignored, change errno from \ + EINVAL to EPIPE. */ \ + errno = EPIPE; \ + } \ + } \ + return ret; \ + } + +# if !REPLACE_PRINTF_POSIX /* avoid collision with printf.c */ +int +printf (const char *format, ...) +{ + int retval; + va_list args; + + va_start (args, format); + retval = vfprintf (stdout, format, args); + va_end (args); + + return retval; +} +# endif + +# if !REPLACE_FPRINTF_POSIX /* avoid collision with fprintf.c */ +int +fprintf (FILE *stream, const char *format, ...) +{ + int retval; + va_list args; + + va_start (args, format); + retval = vfprintf (stream, format, args); + va_end (args); + + return retval; +} +# endif + +# if !REPLACE_VFPRINTF_POSIX /* avoid collision with vprintf.c */ +int +vprintf (const char *format, va_list args) +{ + return vfprintf (stdout, format, args); +} +# endif + +# if !REPLACE_VPRINTF_POSIX /* avoid collision with vfprintf.c */ +int +vfprintf (FILE *stream, const char *format, va_list args) +#undef vfprintf +{ + CALL_WITH_SIGPIPE_EMULATION (int, vfprintf (stream, format, args), ret == EOF) +} +# endif + +int +putchar (int c) +{ + return fputc (c, stdout); +} + +int +fputc (int c, FILE *stream) +#undef fputc +{ + CALL_WITH_SIGPIPE_EMULATION (int, fputc (c, stream), ret == EOF) +} + +int +fputs (const char *string, FILE *stream) +#undef fputs +{ + CALL_WITH_SIGPIPE_EMULATION (int, fputs (string, stream), ret == EOF) +} + +int +puts (const char *string) +#undef puts +{ + FILE *stream = stdout; + CALL_WITH_SIGPIPE_EMULATION (int, puts (string), ret == EOF) +} + +size_t +fwrite (const void *ptr, size_t s, size_t n, FILE *stream) +#undef fwrite +{ + CALL_WITH_SIGPIPE_EMULATION (size_t, fwrite (ptr, s, n, stream), ret < n) +} + +# endif +#endif diff --git a/lib/stdio.in.h b/lib/stdio.in.h new file mode 100644 index 000000000..ae681fccc --- /dev/null +++ b/lib/stdio.in.h @@ -0,0 +1,542 @@ +/* A GNU-like . + + Copyright (C) 2004, 2007-2009 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2, 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif + +#if defined __need_FILE || defined __need___FILE +/* Special invocation convention inside glibc header files. */ + +#@INCLUDE_NEXT@ @NEXT_STDIO_H@ + +#else +/* Normal invocation convention. */ + +#ifndef _GL_STDIO_H + +/* The include_next requires a split double-inclusion guard. */ +#@INCLUDE_NEXT@ @NEXT_STDIO_H@ + +#ifndef _GL_STDIO_H +#define _GL_STDIO_H + +#include +#include + +#if (@GNULIB_FSEEKO@ && @REPLACE_FSEEKO@) \ + || (@GNULIB_FTELLO@ && @REPLACE_FTELLO@) \ + || (@GNULIB_GETDELIM@ && !@HAVE_DECL_GETDELIM@) \ + || (@GNULIB_GETLINE@ && (!@HAVE_DECL_GETLINE@ || @REPLACE_GETLINE@)) +/* Get off_t and ssize_t. */ +# include +#endif + +#ifndef __attribute__ +/* This feature is available in gcc versions 2.5 and later. */ +# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) +# define __attribute__(Spec) /* empty */ +# endif +/* The __-protected variants of `format' and `printf' attributes + are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */ +# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) +# define __format__ format +# define __printf__ printf +# endif +#endif + + +/* The definition of GL_LINK_WARNING is copied here. */ + + +#ifdef __cplusplus +extern "C" { +#endif + + +#if @GNULIB_FPRINTF_POSIX@ +# if @REPLACE_FPRINTF@ +# define fprintf rpl_fprintf +extern int fprintf (FILE *fp, const char *format, ...) + __attribute__ ((__format__ (__printf__, 2, 3))); +# endif +#elif @GNULIB_FPRINTF@ && @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@ +# define fprintf rpl_fprintf +extern int fprintf (FILE *fp, const char *format, ...) + __attribute__ ((__format__ (__printf__, 2, 3))); +#elif defined GNULIB_POSIXCHECK +# undef fprintf +# define fprintf \ + (GL_LINK_WARNING ("fprintf is not always POSIX compliant - " \ + "use gnulib module fprintf-posix for portable " \ + "POSIX compliance"), \ + fprintf) +#endif + +#if @GNULIB_VFPRINTF_POSIX@ +# if @REPLACE_VFPRINTF@ +# define vfprintf rpl_vfprintf +extern int vfprintf (FILE *fp, const char *format, va_list args) + __attribute__ ((__format__ (__printf__, 2, 0))); +# endif +#elif @GNULIB_VFPRINTF@ && @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@ +# define vfprintf rpl_vfprintf +extern int vfprintf (FILE *fp, const char *format, va_list args) + __attribute__ ((__format__ (__printf__, 2, 0))); +#elif defined GNULIB_POSIXCHECK +# undef vfprintf +# define vfprintf(s,f,a) \ + (GL_LINK_WARNING ("vfprintf is not always POSIX compliant - " \ + "use gnulib module vfprintf-posix for portable " \ + "POSIX compliance"), \ + vfprintf (s, f, a)) +#endif + +#if @GNULIB_PRINTF_POSIX@ +# if @REPLACE_PRINTF@ +/* Don't break __attribute__((format(printf,M,N))). */ +# define printf __printf__ +extern int printf (const char *format, ...) + __attribute__ ((__format__ (__printf__, 1, 2))); +# endif +#elif @GNULIB_PRINTF@ && @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@ +/* Don't break __attribute__((format(printf,M,N))). */ +# define printf __printf__ +extern int printf (const char *format, ...) + __attribute__ ((__format__ (__printf__, 1, 2))); +#elif defined GNULIB_POSIXCHECK +# undef printf +# define printf \ + (GL_LINK_WARNING ("printf is not always POSIX compliant - " \ + "use gnulib module printf-posix for portable " \ + "POSIX compliance"), \ + printf) +/* Don't break __attribute__((format(printf,M,N))). */ +# define format(kind,m,n) format (__##kind##__, m, n) +# define __format__(kind,m,n) __format__ (__##kind##__, m, n) +# define ____printf____ __printf__ +# define ____scanf____ __scanf__ +# define ____strftime____ __strftime__ +# define ____strfmon____ __strfmon__ +#endif + +#if @GNULIB_VPRINTF_POSIX@ +# if @REPLACE_VPRINTF@ +# define vprintf rpl_vprintf +extern int vprintf (const char *format, va_list args) + __attribute__ ((__format__ (__printf__, 1, 0))); +# endif +#elif @GNULIB_VPRINTF@ && @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@ +# define vprintf rpl_vprintf +extern int vprintf (const char *format, va_list args) + __attribute__ ((__format__ (__printf__, 1, 0))); +#elif defined GNULIB_POSIXCHECK +# undef vprintf +# define vprintf(f,a) \ + (GL_LINK_WARNING ("vprintf is not always POSIX compliant - " \ + "use gnulib module vprintf-posix for portable " \ + "POSIX compliance"), \ + vprintf (f, a)) +#endif + +#if @GNULIB_SNPRINTF@ +# if @REPLACE_SNPRINTF@ +# define snprintf rpl_snprintf +# endif +# if @REPLACE_SNPRINTF@ || !@HAVE_DECL_SNPRINTF@ +extern int snprintf (char *str, size_t size, const char *format, ...) + __attribute__ ((__format__ (__printf__, 3, 4))); +# endif +#elif defined GNULIB_POSIXCHECK +# undef snprintf +# define snprintf \ + (GL_LINK_WARNING ("snprintf is unportable - " \ + "use gnulib module snprintf for portability"), \ + snprintf) +#endif + +#if @GNULIB_VSNPRINTF@ +# if @REPLACE_VSNPRINTF@ +# define vsnprintf rpl_vsnprintf +# endif +# if @REPLACE_VSNPRINTF@ || !@HAVE_DECL_VSNPRINTF@ +extern int vsnprintf (char *str, size_t size, const char *format, va_list args) + __attribute__ ((__format__ (__printf__, 3, 0))); +# endif +#elif defined GNULIB_POSIXCHECK +# undef vsnprintf +# define vsnprintf(b,s,f,a) \ + (GL_LINK_WARNING ("vsnprintf is unportable - " \ + "use gnulib module vsnprintf for portability"), \ + vsnprintf (b, s, f, a)) +#endif + +#if @GNULIB_SPRINTF_POSIX@ +# if @REPLACE_SPRINTF@ +# define sprintf rpl_sprintf +extern int sprintf (char *str, const char *format, ...) + __attribute__ ((__format__ (__printf__, 2, 3))); +# endif +#elif defined GNULIB_POSIXCHECK +# undef sprintf +# define sprintf \ + (GL_LINK_WARNING ("sprintf is not always POSIX compliant - " \ + "use gnulib module sprintf-posix for portable " \ + "POSIX compliance"), \ + sprintf) +#endif + +#if @GNULIB_VSPRINTF_POSIX@ +# if @REPLACE_VSPRINTF@ +# define vsprintf rpl_vsprintf +extern int vsprintf (char *str, const char *format, va_list args) + __attribute__ ((__format__ (__printf__, 2, 0))); +# endif +#elif defined GNULIB_POSIXCHECK +# undef vsprintf +# define vsprintf(b,f,a) \ + (GL_LINK_WARNING ("vsprintf is not always POSIX compliant - " \ + "use gnulib module vsprintf-posix for portable " \ + "POSIX compliance"), \ + vsprintf (b, f, a)) +#endif + +#if @GNULIB_DPRINTF@ +# if @REPLACE_DPRINTF@ +# define dprintf rpl_dprintf +# endif +# if @REPLACE_DPRINTF@ || !@HAVE_DPRINTF@ +extern int dprintf (int fd, const char *format, ...) + __attribute__ ((__format__ (__printf__, 2, 3))); +# endif +#elif defined GNULIB_POSIXCHECK +# undef dprintf +# define dprintf(d,f,a) \ + (GL_LINK_WARNING ("dprintf is unportable - " \ + "use gnulib module dprintf for portability"), \ + dprintf (d, f, a)) +#endif + +#if @GNULIB_VDPRINTF@ +# if @REPLACE_VDPRINTF@ +# define vdprintf rpl_vdprintf +# endif +# if @REPLACE_VDPRINTF@ || !@HAVE_VDPRINTF@ +extern int vdprintf (int fd, const char *format, va_list args) + __attribute__ ((__format__ (__printf__, 2, 0))); +# endif +#elif defined GNULIB_POSIXCHECK +# undef vdprintf +# define vdprintf(d,f,a) \ + (GL_LINK_WARNING ("vdprintf is unportable - " \ + "use gnulib module vdprintf for portability"), \ + vdprintf (d, f, a)) +#endif + +#if @GNULIB_VASPRINTF@ +# if @REPLACE_VASPRINTF@ +# define asprintf rpl_asprintf +# define vasprintf rpl_vasprintf +# endif +# if @REPLACE_VASPRINTF@ || !@HAVE_VASPRINTF@ + /* Write formatted output to a string dynamically allocated with malloc(). + If the memory allocation succeeds, store the address of the string in + *RESULT and return the number of resulting bytes, excluding the trailing + NUL. Upon memory allocation error, or some other error, return -1. */ + extern int asprintf (char **result, const char *format, ...) + __attribute__ ((__format__ (__printf__, 2, 3))); + extern int vasprintf (char **result, const char *format, va_list args) + __attribute__ ((__format__ (__printf__, 2, 0))); +# endif +#endif + +#if @GNULIB_OBSTACK_PRINTF@ +# if @REPLACE_OBSTACK_PRINTF@ +# define obstack_printf rpl_osbtack_printf +# define obstack_vprintf rpl_obstack_vprintf +# endif +# if @REPLACE_OBSTACK_PRINTF@ || !@HAVE_DECL_OBSTACK_PRINTF@ + struct obstack; + /* Grow an obstack with formatted output. Return the number of + bytes added to OBS. No trailing nul byte is added, and the + object should be closed with obstack_finish before use. Upon + memory allocation error, call obstack_alloc_failed_handler. Upon + other error, return -1. */ + extern int obstack_printf (struct obstack *obs, const char *format, ...) + __attribute__ ((__format__ (__printf__, 2, 3))); + extern int obstack_vprintf (struct obstack *obs, const char *format, + va_list args) + __attribute__ ((__format__ (__printf__, 2, 0))); +# endif +#endif + +#if @GNULIB_FOPEN@ +# if @REPLACE_FOPEN@ +# undef fopen +# define fopen rpl_fopen +extern FILE * fopen (const char *filename, const char *mode); +# endif +#elif defined GNULIB_POSIXCHECK +# undef fopen +# define fopen(f,m) \ + (GL_LINK_WARNING ("fopen on Win32 platforms is not POSIX compatible - " \ + "use gnulib module fopen for portability"), \ + fopen (f, m)) +#endif + +#if @GNULIB_FREOPEN@ +# if @REPLACE_FREOPEN@ +# undef freopen +# define freopen rpl_freopen +extern FILE * freopen (const char *filename, const char *mode, FILE *stream); +# endif +#elif defined GNULIB_POSIXCHECK +# undef freopen +# define freopen(f,m,s) \ + (GL_LINK_WARNING ("freopen on Win32 platforms is not POSIX compatible - " \ + "use gnulib module freopen for portability"), \ + freopen (f, m, s)) +#endif + +#if @GNULIB_FSEEKO@ +# if @REPLACE_FSEEKO@ +/* Provide fseek, fseeko functions that are aware of a preceding + fflush(), and which detect pipes. */ +# define fseeko rpl_fseeko +extern int fseeko (FILE *fp, off_t offset, int whence); +# define fseek(fp, offset, whence) fseeko (fp, (off_t)(offset), whence) +# endif +#elif defined GNULIB_POSIXCHECK +# undef fseeko +# define fseeko(f,o,w) \ + (GL_LINK_WARNING ("fseeko is unportable - " \ + "use gnulib module fseeko for portability"), \ + fseeko (f, o, w)) +#endif + +#if @GNULIB_FSEEK@ && @REPLACE_FSEEK@ +extern int rpl_fseek (FILE *fp, long offset, int whence); +# undef fseek +# if defined GNULIB_POSIXCHECK +# define fseek(f,o,w) \ + (GL_LINK_WARNING ("fseek cannot handle files larger than 4 GB " \ + "on 32-bit platforms - " \ + "use fseeko function for handling of large files"), \ + rpl_fseek (f, o, w)) +# else +# define fseek rpl_fseek +# endif +#elif defined GNULIB_POSIXCHECK +# ifndef fseek +# define fseek(f,o,w) \ + (GL_LINK_WARNING ("fseek cannot handle files larger than 4 GB " \ + "on 32-bit platforms - " \ + "use fseeko function for handling of large files"), \ + fseek (f, o, w)) +# endif +#endif + +#if @GNULIB_FTELLO@ +# if @REPLACE_FTELLO@ +# define ftello rpl_ftello +extern off_t ftello (FILE *fp); +# define ftell(fp) ftello (fp) +# endif +#elif defined GNULIB_POSIXCHECK +# undef ftello +# define ftello(f) \ + (GL_LINK_WARNING ("ftello is unportable - " \ + "use gnulib module ftello for portability"), \ + ftello (f)) +#endif + +#if @GNULIB_FTELL@ && @REPLACE_FTELL@ +extern long rpl_ftell (FILE *fp); +# undef ftell +# if GNULIB_POSIXCHECK +# define ftell(f) \ + (GL_LINK_WARNING ("ftell cannot handle files larger than 4 GB " \ + "on 32-bit platforms - " \ + "use ftello function for handling of large files"), \ + rpl_ftell (f)) +# else +# define ftell rpl_ftell +# endif +#elif defined GNULIB_POSIXCHECK +# ifndef ftell +# define ftell(f) \ + (GL_LINK_WARNING ("ftell cannot handle files larger than 4 GB " \ + "on 32-bit platforms - " \ + "use ftello function for handling of large files"), \ + ftell (f)) +# endif +#endif + +#if @GNULIB_FFLUSH@ +# if @REPLACE_FFLUSH@ +# define fflush rpl_fflush + /* Flush all pending data on STREAM according to POSIX rules. Both + output and seekable input streams are supported. + Note! LOSS OF DATA can occur if fflush is applied on an input stream + that is _not_seekable_ or on an update stream that is _not_seekable_ + and in which the most recent operation was input. Seekability can + be tested with lseek(fileno(fp),0,SEEK_CUR). */ + extern int fflush (FILE *gl_stream); +# endif +#elif defined GNULIB_POSIXCHECK +# undef fflush +# define fflush(f) \ + (GL_LINK_WARNING ("fflush is not always POSIX compliant - " \ + "use gnulib module fflush for portable " \ + "POSIX compliance"), \ + fflush (f)) +#endif + +#if @GNULIB_FPURGE@ +# if @REPLACE_FPURGE@ +# define fpurge rpl_fpurge +# endif +# if @REPLACE_FPURGE@ || !@HAVE_DECL_FPURGE@ + /* Discard all pending buffered I/O data on STREAM. + STREAM must not be wide-character oriented. + Return 0 if successful. Upon error, return -1 and set errno. */ + extern int fpurge (FILE *gl_stream); +# endif +#elif defined GNULIB_POSIXCHECK +# undef fpurge +# define fpurge(f) \ + (GL_LINK_WARNING ("fpurge is not always present - " \ + "use gnulib module fpurge for portability"), \ + fpurge (f)) +#endif + +#if @GNULIB_FCLOSE@ +# if @REPLACE_FCLOSE@ +# define fclose rpl_fclose + /* Close STREAM and its underlying file descriptor. */ +extern int fclose (FILE *stream); +# endif +#elif defined GNULIB_POSIXCHECK +# undef fclose +# define fclose(f) \ + (GL_LINK_WARNING ("fclose is not always POSIX compliant - " \ + "use gnulib module fclose for portable " \ + "POSIX compliance"), \ + fclose (f)) +#endif + +#if @GNULIB_FPUTC@ && @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@ +# undef fputc +# define fputc rpl_fputc +extern int fputc (int c, FILE *stream); +#endif + +#if @GNULIB_PUTC@ && @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@ +# undef putc +# define putc rpl_fputc +extern int putc (int c, FILE *stream); +#endif + +#if @GNULIB_PUTCHAR@ && @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@ +# undef putchar +# define putchar rpl_putchar +extern int putchar (int c); +#endif + +#if @GNULIB_FPUTS@ && @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@ +# undef fputs +# define fputs rpl_fputs +extern int fputs (const char *string, FILE *stream); +#endif + +#if @GNULIB_PUTS@ && @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@ +# undef puts +# define puts rpl_puts +extern int puts (const char *string); +#endif + +#if @GNULIB_FWRITE@ && @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@ +# undef fwrite +# define fwrite rpl_fwrite +extern size_t fwrite (const void *ptr, size_t s, size_t n, FILE *stream); +#endif + +#if @GNULIB_GETDELIM@ +# if !@HAVE_DECL_GETDELIM@ +/* Read input, up to (and including) the next occurrence of DELIMITER, from + STREAM, store it in *LINEPTR (and NUL-terminate it). + *LINEPTR is a pointer returned from malloc (or NULL), pointing to *LINESIZE + bytes of space. It is realloc'd as necessary. + Return the number of bytes read and stored at *LINEPTR (not including the + NUL terminator), or -1 on error or EOF. */ +extern ssize_t getdelim (char **lineptr, size_t *linesize, int delimiter, + FILE *stream); +# endif +#elif defined GNULIB_POSIXCHECK +# undef getdelim +# define getdelim(l, s, d, f) \ + (GL_LINK_WARNING ("getdelim is unportable - " \ + "use gnulib module getdelim for portability"), \ + getdelim (l, s, d, f)) +#endif + +#if @GNULIB_GETLINE@ +# if @REPLACE_GETLINE@ +# undef getline +# define getline rpl_getline +# endif +# if !@HAVE_DECL_GETLINE@ || @REPLACE_GETLINE@ +/* Read a line, up to (and including) the next newline, from STREAM, store it + in *LINEPTR (and NUL-terminate it). + *LINEPTR is a pointer returned from malloc (or NULL), pointing to *LINESIZE + bytes of space. It is realloc'd as necessary. + Return the number of bytes read and stored at *LINEPTR (not including the + NUL terminator), or -1 on error or EOF. */ +extern ssize_t getline (char **lineptr, size_t *linesize, FILE *stream); +# endif +#elif defined GNULIB_POSIXCHECK +# undef getline +# define getline(l, s, f) \ + (GL_LINK_WARNING ("getline is unportable - " \ + "use gnulib module getline for portability"), \ + getline (l, s, f)) +#endif + +#if @GNULIB_PERROR@ +# if @REPLACE_PERROR@ +# define perror rpl_perror +/* Print a message to standard error, describing the value of ERRNO, + (if STRING is not NULL and not empty) prefixed with STRING and ": ", + and terminated with a newline. */ +extern void perror (const char *string); +# endif +#elif defined GNULIB_POSIXCHECK +# undef perror +# define perror(s) \ + (GL_LINK_WARNING ("perror is not always POSIX compliant - " \ + "use gnulib module perror for portability"), \ + perror (s)) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _GL_STDIO_H */ +#endif /* _GL_STDIO_H */ +#endif diff --git a/lib/stdlib.in.h b/lib/stdlib.in.h new file mode 100644 index 000000000..23325b563 --- /dev/null +++ b/lib/stdlib.in.h @@ -0,0 +1,383 @@ +/* A GNU-like . + + Copyright (C) 1995, 2001-2004, 2006-2009 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif + +#if defined __need_malloc_and_calloc +/* Special invocation convention inside glibc header files. */ + +#@INCLUDE_NEXT@ @NEXT_STDLIB_H@ + +#else +/* Normal invocation convention. */ + +#ifndef _GL_STDLIB_H + +/* The include_next requires a split double-inclusion guard. */ +#@INCLUDE_NEXT@ @NEXT_STDLIB_H@ + +#ifndef _GL_STDLIB_H +#define _GL_STDLIB_H + + +/* Solaris declares getloadavg() in . */ +#if @GNULIB_GETLOADAVG@ && @HAVE_SYS_LOADAVG_H@ +# include +#endif + +/* OSF/1 5.1 declares 'struct random_data' in , which is included + from if _REENTRANT is defined. Include it always. */ +#if @HAVE_RANDOM_H@ +# include +#endif + +#if @GNULIB_RANDOM_R@ || !@HAVE_STRUCT_RANDOM_DATA@ +# include +#endif + +#if !@HAVE_STRUCT_RANDOM_DATA@ +struct random_data +{ + int32_t *fptr; /* Front pointer. */ + int32_t *rptr; /* Rear pointer. */ + int32_t *state; /* Array of state values. */ + int rand_type; /* Type of random number generator. */ + int rand_deg; /* Degree of random number generator. */ + int rand_sep; /* Distance between front and rear. */ + int32_t *end_ptr; /* Pointer behind state table. */ +}; +#endif + +/* The definition of GL_LINK_WARNING is copied here. */ + + +/* Some systems do not define EXIT_*, despite otherwise supporting C89. */ +#ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +#endif +/* Tandem/NSK and other platforms that define EXIT_FAILURE as -1 interfere + with proper operation of xargs. */ +#ifndef EXIT_FAILURE +# define EXIT_FAILURE 1 +#elif EXIT_FAILURE != 1 +# undef EXIT_FAILURE +# define EXIT_FAILURE 1 +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + + +#if @GNULIB_MALLOC_POSIX@ +# if !@HAVE_MALLOC_POSIX@ +# undef malloc +# define malloc rpl_malloc +extern void * malloc (size_t size); +# endif +#elif defined GNULIB_POSIXCHECK +# undef malloc +# define malloc(s) \ + (GL_LINK_WARNING ("malloc is not POSIX compliant everywhere - " \ + "use gnulib module malloc-posix for portability"), \ + malloc (s)) +#endif + + +#if @GNULIB_REALLOC_POSIX@ +# if !@HAVE_REALLOC_POSIX@ +# undef realloc +# define realloc rpl_realloc +extern void * realloc (void *ptr, size_t size); +# endif +#elif defined GNULIB_POSIXCHECK +# undef realloc +# define realloc(p,s) \ + (GL_LINK_WARNING ("realloc is not POSIX compliant everywhere - " \ + "use gnulib module realloc-posix for portability"), \ + realloc (p, s)) +#endif + + +#if @GNULIB_CALLOC_POSIX@ +# if !@HAVE_CALLOC_POSIX@ +# undef calloc +# define calloc rpl_calloc +extern void * calloc (size_t nmemb, size_t size); +# endif +#elif defined GNULIB_POSIXCHECK +# undef calloc +# define calloc(n,s) \ + (GL_LINK_WARNING ("calloc is not POSIX compliant everywhere - " \ + "use gnulib module calloc-posix for portability"), \ + calloc (n, s)) +#endif + + +#if @GNULIB_ATOLL@ +# if !@HAVE_ATOLL@ +/* Parse a signed decimal integer. + Returns the value of the integer. Errors are not detected. */ +extern long long atoll (const char *string); +# endif +#elif defined GNULIB_POSIXCHECK +# undef atoll +# define atoll(s) \ + (GL_LINK_WARNING ("atoll is unportable - " \ + "use gnulib module atoll for portability"), \ + atoll (s)) +#endif + + +#if @GNULIB_GETLOADAVG@ +# if !@HAVE_DECL_GETLOADAVG@ +/* Store max(NELEM,3) load average numbers in LOADAVG[]. + The three numbers are the load average of the last 1 minute, the last 5 + minutes, and the last 15 minutes, respectively. + LOADAVG is an array of NELEM numbers. */ +extern int getloadavg (double loadavg[], int nelem); +# endif +#elif defined GNULIB_POSIXCHECK +# undef getloadavg +# define getloadavg(l,n) \ + (GL_LINK_WARNING ("getloadavg is not portable - " \ + "use gnulib module getloadavg for portability"), \ + getloadavg (l, n)) +#endif + + +#if @GNULIB_GETSUBOPT@ +/* Assuming *OPTIONP is a comma separated list of elements of the form + "token" or "token=value", getsubopt parses the first of these elements. + If the first element refers to a "token" that is member of the given + NULL-terminated array of tokens: + - It replaces the comma with a NUL byte, updates *OPTIONP to point past + the first option and the comma, sets *VALUEP to the value of the + element (or NULL if it doesn't contain an "=" sign), + - It returns the index of the "token" in the given array of tokens. + Otherwise it returns -1, and *OPTIONP and *VALUEP are undefined. + For more details see the POSIX:2001 specification. + http://www.opengroup.org/susv3xsh/getsubopt.html */ +# if !@HAVE_GETSUBOPT@ +extern int getsubopt (char **optionp, char *const *tokens, char **valuep); +# endif +#elif defined GNULIB_POSIXCHECK +# undef getsubopt +# define getsubopt(o,t,v) \ + (GL_LINK_WARNING ("getsubopt is unportable - " \ + "use gnulib module getsubopt for portability"), \ + getsubopt (o, t, v)) +#endif + + +#if @GNULIB_MKDTEMP@ +# if !@HAVE_MKDTEMP@ +/* Create a unique temporary directory from TEMPLATE. + The last six characters of TEMPLATE must be "XXXXXX"; + they are replaced with a string that makes the directory name unique. + Returns TEMPLATE, or a null pointer if it cannot get a unique name. + The directory is created mode 700. */ +extern char * mkdtemp (char * /*template*/); +# endif +#elif defined GNULIB_POSIXCHECK +# undef mkdtemp +# define mkdtemp(t) \ + (GL_LINK_WARNING ("mkdtemp is unportable - " \ + "use gnulib module mkdtemp for portability"), \ + mkdtemp (t)) +#endif + + +#if @GNULIB_MKSTEMP@ +# if @REPLACE_MKSTEMP@ +/* Create a unique temporary file from TEMPLATE. + The last six characters of TEMPLATE must be "XXXXXX"; + they are replaced with a string that makes the file name unique. + The file is then created, ensuring it didn't exist before. + The file is created read-write (mask at least 0600 & ~umask), but it may be + world-readable and world-writable (mask 0666 & ~umask), depending on the + implementation. + Returns the open file descriptor if successful, otherwise -1 and errno + set. */ +# define mkstemp rpl_mkstemp +extern int mkstemp (char * /*template*/); +# else +/* On MacOS X 10.3, only declares mkstemp. */ +# include +# endif +#elif defined GNULIB_POSIXCHECK +# undef mkstemp +# define mkstemp(t) \ + (GL_LINK_WARNING ("mkstemp is unportable - " \ + "use gnulib module mkstemp for portability"), \ + mkstemp (t)) +#endif + + +#if @GNULIB_PUTENV@ +# if @REPLACE_PUTENV@ +# undef putenv +# define putenv rpl_putenv +extern int putenv (char *string); +# endif +#endif + + +#if @GNULIB_RANDOM_R@ +# if !@HAVE_RANDOM_R@ + +# ifndef RAND_MAX +# define RAND_MAX 2147483647 +# endif + +int srandom_r (unsigned int seed, struct random_data *rand_state); +int initstate_r (unsigned int seed, char *buf, size_t buf_size, + struct random_data *rand_state); +int setstate_r (char *arg_state, struct random_data *rand_state); +int random_r (struct random_data *buf, int32_t *result); +# endif +#elif defined GNULIB_POSIXCHECK +# undef random_r +# define random_r(b,r) \ + (GL_LINK_WARNING ("random_r is unportable - " \ + "use gnulib module random_r for portability"), \ + random_r (b,r)) +# undef initstate_r +# define initstate_r(s,b,sz,r) \ + (GL_LINK_WARNING ("initstate_r is unportable - " \ + "use gnulib module random_r for portability"), \ + initstate_r (s,b,sz,r)) +# undef srandom_r +# define srandom_r(s,r) \ + (GL_LINK_WARNING ("srandom_r is unportable - " \ + "use gnulib module random_r for portability"), \ + srandom_r (s,r)) +# undef setstate_r +# define setstate_r(a,r) \ + (GL_LINK_WARNING ("setstate_r is unportable - " \ + "use gnulib module random_r for portability"), \ + setstate_r (a,r)) +#endif + + +#if @GNULIB_RPMATCH@ +# if !@HAVE_RPMATCH@ +/* Test a user response to a question. + Return 1 if it is affirmative, 0 if it is negative, or -1 if not clear. */ +extern int rpmatch (const char *response); +# endif +#elif defined GNULIB_POSIXCHECK +# undef rpmatch +# define rpmatch(r) \ + (GL_LINK_WARNING ("rpmatch is unportable - " \ + "use gnulib module rpmatch for portability"), \ + rpmatch (r)) +#endif + + +#if @GNULIB_SETENV@ +# if !@HAVE_SETENV@ +/* Set NAME to VALUE in the environment. + If REPLACE is nonzero, overwrite an existing value. */ +extern int setenv (const char *name, const char *value, int replace); +# endif +#endif + + +#if @GNULIB_UNSETENV@ +# if @HAVE_UNSETENV@ +# if @VOID_UNSETENV@ +/* On some systems, unsetenv() returns void. + This is the case for MacOS X 10.3, FreeBSD 4.8, NetBSD 1.6, OpenBSD 3.4. */ +# define unsetenv(name) ((unsetenv)(name), 0) +# endif +# else +/* Remove the variable NAME from the environment. */ +extern int unsetenv (const char *name); +# endif +#endif + + +#if @GNULIB_STRTOD@ +# if @REPLACE_STRTOD@ +# define strtod rpl_strtod +# endif +# if !@HAVE_STRTOD@ || @REPLACE_STRTOD@ + /* Parse a double from STRING, updating ENDP if appropriate. */ +extern double strtod (const char *str, char **endp); +# endif +#elif defined GNULIB_POSIXCHECK +# undef strtod +# define strtod(s, e) \ + (GL_LINK_WARNING ("strtod is unportable - " \ + "use gnulib module strtod for portability"), \ + strtod (s, e)) +#endif + + +#if @GNULIB_STRTOLL@ +# if !@HAVE_STRTOLL@ +/* Parse a signed integer whose textual representation starts at STRING. + The integer is expected to be in base BASE (2 <= BASE <= 36); if BASE == 0, + it may be decimal or octal (with prefix "0") or hexadecimal (with prefix + "0x"). + If ENDPTR is not NULL, the address of the first byte after the integer is + stored in *ENDPTR. + Upon overflow, the return value is LLONG_MAX or LLONG_MIN, and errno is set + to ERANGE. */ +extern long long strtoll (const char *string, char **endptr, int base); +# endif +#elif defined GNULIB_POSIXCHECK +# undef strtoll +# define strtoll(s,e,b) \ + (GL_LINK_WARNING ("strtoll is unportable - " \ + "use gnulib module strtoll for portability"), \ + strtoll (s, e, b)) +#endif + + +#if @GNULIB_STRTOULL@ +# if !@HAVE_STRTOULL@ +/* Parse an unsigned integer whose textual representation starts at STRING. + The integer is expected to be in base BASE (2 <= BASE <= 36); if BASE == 0, + it may be decimal or octal (with prefix "0") or hexadecimal (with prefix + "0x"). + If ENDPTR is not NULL, the address of the first byte after the integer is + stored in *ENDPTR. + Upon overflow, the return value is ULLONG_MAX, and errno is set to + ERANGE. */ +extern unsigned long long strtoull (const char *string, char **endptr, int base); +# endif +#elif defined GNULIB_POSIXCHECK +# undef strtoull +# define strtoull(s,e,b) \ + (GL_LINK_WARNING ("strtoull is unportable - " \ + "use gnulib module strtoull for portability"), \ + strtoull (s, e, b)) +#endif + + +#ifdef __cplusplus +} +#endif + +#endif /* _GL_STDLIB_H */ +#endif /* _GL_STDLIB_H */ +#endif diff --git a/lib/strftime.c b/lib/strftime.c index ac011d431..e3402237e 100644 --- a/lib/strftime.c +++ b/lib/strftime.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991-1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007 Free Software +/* Copyright (C) 1991-1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007, 2009 Free Software Foundation, Inc. NOTE: The canonical source of this file is maintained with the GNU C Library. @@ -18,19 +18,18 @@ along with this program. If not, see . */ #ifdef _LIBC -# define HAVE_MBLEN 1 -# define HAVE_MBRLEN 1 # define HAVE_STRUCT_ERA_ENTRY 1 # define HAVE_TM_GMTOFF 1 # define HAVE_TM_ZONE 1 # define HAVE_TZNAME 1 # define HAVE_TZSET 1 -# define MULTIBYTE_IS_FORMAT_SAFE 1 # include "../locale/localeinfo.h" #else # include # if FPRINTFTIME # include "fprintftime.h" +# else +# include "strftime.h" # endif #endif @@ -44,10 +43,16 @@ extern char *tzname[]; /* Do multibyte processing if multibytes are supported, unless multibyte sequences are safe in formats. Multibyte sequences are safe if they cannot contain byte sequences that look like format - conversion specifications. The GNU C Library uses UTF8 multibyte - encoding, which is safe for formats, but strftime.c can be used - with other C libraries that use unsafe encodings. */ -#define DO_MULTIBYTE (HAVE_MBLEN && ! MULTIBYTE_IS_FORMAT_SAFE) + conversion specifications. The multibyte encodings used by the + C library on the various platforms (UTF-8, GB2312, GBK, CP936, + GB18030, EUC-TW, BIG5, BIG5-HKSCS, CP950, EUC-JP, EUC-KR, CP949, + SHIFT_JIS, CP932, JOHAB) are safe for formats, because the byte '%' + cannot occur in a multibyte character except in the first byte. + But this does not hold for the DEC-HANYU encoding used on OSF/1. */ +#if !defined __osf__ +# define MULTIBYTE_IS_FORMAT_SAFE 1 +#endif +#define DO_MULTIBYTE (! MULTIBYTE_IS_FORMAT_SAFE) #if DO_MULTIBYTE # include @@ -79,13 +84,6 @@ extern char *tzname[]; # define MEMCPY(d, s, n) memcpy (d, s, n) # define STRLEN(s) strlen (s) -# ifdef _LIBC -# define MEMPCPY(d, s, n) __mempcpy (d, s, n) -# else -# ifndef HAVE_MEMPCPY -# define MEMPCPY(d, s, n) ((void *) ((char *) memcpy (d, s, n) + (n))) -# endif -# endif #endif /* Shift A right by B bits portably, by dividing A by 2**B and diff --git a/lib/striconveh.c b/lib/striconveh.c new file mode 100644 index 000000000..b39a01f19 --- /dev/null +++ b/lib/striconveh.c @@ -0,0 +1,1251 @@ +/* Character set conversion with error handling. + Copyright (C) 2001-2008 Free Software Foundation, Inc. + Written by Bruno Haible and Simon Josefsson. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#include + +/* Specification. */ +#include "striconveh.h" + +#include +#include +#include +#include + +#if HAVE_ICONV +# include +# include "unistr.h" +#endif + +#include "c-strcase.h" +#include "c-strcaseeq.h" + +#ifndef SIZE_MAX +# define SIZE_MAX ((size_t) -1) +#endif + + +#if HAVE_ICONV + +/* The caller must provide CD, CD1, CD2, not just CD, because when a conversion + error occurs, we may have to determine the Unicode representation of the + inconvertible character. */ + +/* iconv_carefully is like iconv, except that it stops as soon as it encounters + a conversion error, and it returns in *INCREMENTED a boolean telling whether + it has incremented the input pointers past the error location. */ +# if !defined _LIBICONV_VERSION && !defined __GLIBC__ +/* Irix iconv() inserts a NUL byte if it cannot convert. + NetBSD iconv() inserts a question mark if it cannot convert. + Only GNU libiconv and GNU libc are known to prefer to fail rather + than doing a lossy conversion. */ +static size_t +iconv_carefully (iconv_t cd, + const char **inbuf, size_t *inbytesleft, + char **outbuf, size_t *outbytesleft, + bool *incremented) +{ + const char *inptr = *inbuf; + const char *inptr_end = inptr + *inbytesleft; + char *outptr = *outbuf; + size_t outsize = *outbytesleft; + const char *inptr_before; + size_t res; + + do + { + size_t insize; + + inptr_before = inptr; + res = (size_t)(-1); + + for (insize = 1; inptr + insize <= inptr_end; insize++) + { + res = iconv (cd, + (ICONV_CONST char **) &inptr, &insize, + &outptr, &outsize); + if (!(res == (size_t)(-1) && errno == EINVAL)) + break; + /* iconv can eat up a shift sequence but give EINVAL while attempting + to convert the first character. E.g. libiconv does this. */ + if (inptr > inptr_before) + { + res = 0; + break; + } + } + + if (res == 0) + { + *outbuf = outptr; + *outbytesleft = outsize; + } + } + while (res == 0 && inptr < inptr_end); + + *inbuf = inptr; + *inbytesleft = inptr_end - inptr; + if (res != (size_t)(-1) && res > 0) + { + /* iconv() has already incremented INPTR. We cannot go back to a + previous INPTR, otherwise the state inside CD would become invalid, + if FROM_CODESET is a stateful encoding. So, tell the caller that + *INBUF has already been incremented. */ + *incremented = (inptr > inptr_before); + errno = EILSEQ; + return (size_t)(-1); + } + else + { + *incremented = false; + return res; + } +} +# else +# define iconv_carefully(cd, inbuf, inbytesleft, outbuf, outbytesleft, incremented) \ + (*(incremented) = false, \ + iconv (cd, (ICONV_CONST char **) (inbuf), inbytesleft, outbuf, outbytesleft)) +# endif + +/* iconv_carefully_1 is like iconv_carefully, except that it stops after + converting one character or one shift sequence. */ +static size_t +iconv_carefully_1 (iconv_t cd, + const char **inbuf, size_t *inbytesleft, + char **outbuf, size_t *outbytesleft, + bool *incremented) +{ + const char *inptr_before = *inbuf; + const char *inptr = inptr_before; + const char *inptr_end = inptr_before + *inbytesleft; + char *outptr = *outbuf; + size_t outsize = *outbytesleft; + size_t res = (size_t)(-1); + size_t insize; + + for (insize = 1; inptr_before + insize <= inptr_end; insize++) + { + inptr = inptr_before; + res = iconv (cd, + (ICONV_CONST char **) &inptr, &insize, + &outptr, &outsize); + if (!(res == (size_t)(-1) && errno == EINVAL)) + break; + /* iconv can eat up a shift sequence but give EINVAL while attempting + to convert the first character. E.g. libiconv does this. */ + if (inptr > inptr_before) + { + res = 0; + break; + } + } + + *inbuf = inptr; + *inbytesleft = inptr_end - inptr; +# if !defined _LIBICONV_VERSION && !defined __GLIBC__ + /* Irix iconv() inserts a NUL byte if it cannot convert. + NetBSD iconv() inserts a question mark if it cannot convert. + Only GNU libiconv and GNU libc are known to prefer to fail rather + than doing a lossy conversion. */ + if (res != (size_t)(-1) && res > 0) + { + /* iconv() has already incremented INPTR. We cannot go back to a + previous INPTR, otherwise the state inside CD would become invalid, + if FROM_CODESET is a stateful encoding. So, tell the caller that + *INBUF has already been incremented. */ + *incremented = (inptr > inptr_before); + errno = EILSEQ; + return (size_t)(-1); + } +# endif + + if (res != (size_t)(-1)) + { + *outbuf = outptr; + *outbytesleft = outsize; + } + *incremented = false; + return res; +} + +/* utf8conv_carefully is like iconv, except that + - it converts from UTF-8 to UTF-8, + - it stops as soon as it encounters a conversion error, and it returns + in *INCREMENTED a boolean telling whether it has incremented the input + pointers past the error location, + - if one_character_only is true, it stops after converting one + character. */ +static size_t +utf8conv_carefully (bool one_character_only, + const char **inbuf, size_t *inbytesleft, + char **outbuf, size_t *outbytesleft, + bool *incremented) +{ + const char *inptr = *inbuf; + size_t insize = *inbytesleft; + char *outptr = *outbuf; + size_t outsize = *outbytesleft; + size_t res; + + res = 0; + do + { + ucs4_t uc; + int n; + int m; + + n = u8_mbtoucr (&uc, (const uint8_t *) inptr, insize); + if (n < 0) + { + errno = (n == -2 ? EINVAL : EILSEQ); + n = u8_mbtouc (&uc, (const uint8_t *) inptr, insize); + inptr += n; + insize -= n; + res = (size_t)(-1); + *incremented = true; + break; + } + if (outsize == 0) + { + errno = E2BIG; + res = (size_t)(-1); + *incremented = false; + break; + } + m = u8_uctomb ((uint8_t *) outptr, uc, outsize); + if (m == -2) + { + errno = E2BIG; + res = (size_t)(-1); + *incremented = false; + break; + } + inptr += n; + insize -= n; + if (m == -1) + { + errno = EILSEQ; + res = (size_t)(-1); + *incremented = true; + break; + } + outptr += m; + outsize -= m; + } + while (!one_character_only && insize > 0); + + *inbuf = inptr; + *inbytesleft = insize; + *outbuf = outptr; + *outbytesleft = outsize; + return res; +} + +static int +mem_cd_iconveh_internal (const char *src, size_t srclen, + iconv_t cd, iconv_t cd1, iconv_t cd2, + enum iconv_ilseq_handler handler, + size_t extra_alloc, + size_t *offsets, + char **resultp, size_t *lengthp) +{ + /* When a conversion error occurs, we cannot start using CD1 and CD2 at + this point: FROM_CODESET may be a stateful encoding like ISO-2022-KR. + Instead, we have to start afresh from the beginning of SRC. */ + /* Use a temporary buffer, so that for small strings, a single malloc() + call will be sufficient. */ +# define tmpbufsize 4096 + /* The alignment is needed when converting e.g. to glibc's WCHAR_T or + libiconv's UCS-4-INTERNAL encoding. */ + union { unsigned int align; char buf[tmpbufsize]; } tmp; +# define tmpbuf tmp.buf + + char *initial_result; + char *result; + size_t allocated; + size_t length; + size_t last_length = (size_t)(-1); /* only needed if offsets != NULL */ + + if (*resultp != NULL && *lengthp >= sizeof (tmpbuf)) + { + initial_result = *resultp; + allocated = *lengthp; + } + else + { + initial_result = tmpbuf; + allocated = sizeof (tmpbuf); + } + result = initial_result; + + /* Test whether a direct conversion is possible at all. */ + if (cd == (iconv_t)(-1)) + goto indirectly; + + if (offsets != NULL) + { + size_t i; + + for (i = 0; i < srclen; i++) + offsets[i] = (size_t)(-1); + + last_length = (size_t)(-1); + } + length = 0; + + /* First, try a direct conversion, and see whether a conversion error + occurs at all. */ + { + const char *inptr = src; + size_t insize = srclen; + + /* Avoid glibc-2.1 bug and Solaris 2.7-2.9 bug. */ +# if defined _LIBICONV_VERSION \ + || !((__GLIBC__ - 0 == 2 && __GLIBC_MINOR__ - 0 <= 1) || defined __sun) + /* Set to the initial state. */ + iconv (cd, NULL, NULL, NULL, NULL); +# endif + + while (insize > 0) + { + char *outptr = result + length; + size_t outsize = allocated - extra_alloc - length; + bool incremented; + size_t res; + bool grow; + + if (offsets != NULL) + { + if (length != last_length) /* ensure that offset[] be increasing */ + { + offsets[inptr - src] = length; + last_length = length; + } + res = iconv_carefully_1 (cd, + &inptr, &insize, + &outptr, &outsize, + &incremented); + } + else + /* Use iconv_carefully instead of iconv here, because: + - If TO_CODESET is UTF-8, we can do the error handling in this + loop, no need for a second loop, + - With iconv() implementations other than GNU libiconv and GNU + libc, if we use iconv() in a big swoop, checking for an E2BIG + return, we lose the number of irreversible conversions. */ + res = iconv_carefully (cd, + &inptr, &insize, + &outptr, &outsize, + &incremented); + + length = outptr - result; + grow = (length + extra_alloc > allocated / 2); + if (res == (size_t)(-1)) + { + if (errno == E2BIG) + grow = true; + else if (errno == EINVAL) + break; + else if (errno == EILSEQ && handler != iconveh_error) + { + if (cd2 == (iconv_t)(-1)) + { + /* TO_CODESET is UTF-8. */ + /* Error handling can produce up to 1 byte of output. */ + if (length + 1 + extra_alloc > allocated) + { + char *memory; + + allocated = 2 * allocated; + if (length + 1 + extra_alloc > allocated) + abort (); + if (result == initial_result) + memory = (char *) malloc (allocated); + else + memory = (char *) realloc (result, allocated); + if (memory == NULL) + { + if (result != initial_result) + free (result); + errno = ENOMEM; + return -1; + } + if (result == initial_result) + memcpy (memory, initial_result, length); + result = memory; + grow = false; + } + /* The input is invalid in FROM_CODESET. Eat up one byte + and emit a question mark. */ + if (!incremented) + { + if (insize == 0) + abort (); + inptr++; + insize--; + } + result[length] = '?'; + length++; + } + else + goto indirectly; + } + else + { + if (result != initial_result) + { + int saved_errno = errno; + free (result); + errno = saved_errno; + } + return -1; + } + } + if (insize == 0) + break; + if (grow) + { + char *memory; + + allocated = 2 * allocated; + if (result == initial_result) + memory = (char *) malloc (allocated); + else + memory = (char *) realloc (result, allocated); + if (memory == NULL) + { + if (result != initial_result) + free (result); + errno = ENOMEM; + return -1; + } + if (result == initial_result) + memcpy (memory, initial_result, length); + result = memory; + } + } + } + + /* Now get the conversion state back to the initial state. + But avoid glibc-2.1 bug and Solaris 2.7 bug. */ +#if defined _LIBICONV_VERSION \ + || !((__GLIBC__ == 2 && __GLIBC_MINOR__ <= 1) || defined __sun) + for (;;) + { + char *outptr = result + length; + size_t outsize = allocated - extra_alloc - length; + size_t res; + + res = iconv (cd, NULL, NULL, &outptr, &outsize); + length = outptr - result; + if (res == (size_t)(-1)) + { + if (errno == E2BIG) + { + char *memory; + + allocated = 2 * allocated; + if (result == initial_result) + memory = (char *) malloc (allocated); + else + memory = (char *) realloc (result, allocated); + if (memory == NULL) + { + if (result != initial_result) + free (result); + errno = ENOMEM; + return -1; + } + if (result == initial_result) + memcpy (memory, initial_result, length); + result = memory; + } + else + { + if (result != initial_result) + { + int saved_errno = errno; + free (result); + errno = saved_errno; + } + return -1; + } + } + else + break; + } +#endif + + /* The direct conversion succeeded. */ + goto done; + + indirectly: + /* The direct conversion failed. + Use a conversion through UTF-8. */ + if (offsets != NULL) + { + size_t i; + + for (i = 0; i < srclen; i++) + offsets[i] = (size_t)(-1); + + last_length = (size_t)(-1); + } + length = 0; + { + const bool slowly = (offsets != NULL || handler == iconveh_error); +# define utf8bufsize 4096 /* may also be smaller or larger than tmpbufsize */ + char utf8buf[utf8bufsize + 1]; + size_t utf8len = 0; + const char *in1ptr = src; + size_t in1size = srclen; + bool do_final_flush1 = true; + bool do_final_flush2 = true; + + /* Avoid glibc-2.1 bug and Solaris 2.7-2.9 bug. */ +# if defined _LIBICONV_VERSION \ + || !((__GLIBC__ - 0 == 2 && __GLIBC_MINOR__ - 0 <= 1) || defined __sun) + /* Set to the initial state. */ + if (cd1 != (iconv_t)(-1)) + iconv (cd1, NULL, NULL, NULL, NULL); + if (cd2 != (iconv_t)(-1)) + iconv (cd2, NULL, NULL, NULL, NULL); +# endif + + while (in1size > 0 || do_final_flush1 || utf8len > 0 || do_final_flush2) + { + char *out1ptr = utf8buf + utf8len; + size_t out1size = utf8bufsize - utf8len; + bool incremented1; + size_t res1; + int errno1; + + /* Conversion step 1: from FROM_CODESET to UTF-8. */ + if (in1size > 0) + { + if (offsets != NULL + && length != last_length) /* ensure that offset[] be increasing */ + { + offsets[in1ptr - src] = length; + last_length = length; + } + if (cd1 != (iconv_t)(-1)) + { + if (slowly) + res1 = iconv_carefully_1 (cd1, + &in1ptr, &in1size, + &out1ptr, &out1size, + &incremented1); + else + res1 = iconv_carefully (cd1, + &in1ptr, &in1size, + &out1ptr, &out1size, + &incremented1); + } + else + { + /* FROM_CODESET is UTF-8. */ + res1 = utf8conv_carefully (slowly, + &in1ptr, &in1size, + &out1ptr, &out1size, + &incremented1); + } + } + else if (do_final_flush1) + { + /* Now get the conversion state of CD1 back to the initial state. + But avoid glibc-2.1 bug and Solaris 2.7 bug. */ +# if defined _LIBICONV_VERSION \ + || !((__GLIBC__ == 2 && __GLIBC_MINOR__ <= 1) || defined __sun) + if (cd1 != (iconv_t)(-1)) + res1 = iconv (cd1, NULL, NULL, &out1ptr, &out1size); + else +# endif + res1 = 0; + do_final_flush1 = false; + incremented1 = true; + } + else + { + res1 = 0; + incremented1 = true; + } + if (res1 == (size_t)(-1) + && !(errno == E2BIG || errno == EINVAL || errno == EILSEQ)) + { + if (result != initial_result) + { + int saved_errno = errno; + free (result); + errno = saved_errno; + } + return -1; + } + if (res1 == (size_t)(-1) + && errno == EILSEQ && handler != iconveh_error) + { + /* The input is invalid in FROM_CODESET. Eat up one byte and + emit a question mark. Room for the question mark was allocated + at the end of utf8buf. */ + if (!incremented1) + { + if (in1size == 0) + abort (); + in1ptr++; + in1size--; + } + utf8buf[utf8len++] = '?'; + } + errno1 = errno; + utf8len = out1ptr - utf8buf; + + if (offsets != NULL + || in1size == 0 + || utf8len > utf8bufsize / 2 + || (res1 == (size_t)(-1) && errno1 == E2BIG)) + { + /* Conversion step 2: from UTF-8 to TO_CODESET. */ + const char *in2ptr = utf8buf; + size_t in2size = utf8len; + + while (in2size > 0 + || (in1size == 0 && !do_final_flush1 && do_final_flush2)) + { + char *out2ptr = result + length; + size_t out2size = allocated - extra_alloc - length; + bool incremented2; + size_t res2; + bool grow; + + if (in2size > 0) + { + if (cd2 != (iconv_t)(-1)) + res2 = iconv_carefully (cd2, + &in2ptr, &in2size, + &out2ptr, &out2size, + &incremented2); + else + /* TO_CODESET is UTF-8. */ + res2 = utf8conv_carefully (false, + &in2ptr, &in2size, + &out2ptr, &out2size, + &incremented2); + } + else /* in1size == 0 && !do_final_flush1 + && in2size == 0 && do_final_flush2 */ + { + /* Now get the conversion state of CD1 back to the initial + state. But avoid glibc-2.1 bug and Solaris 2.7 bug. */ +# if defined _LIBICONV_VERSION \ + || !((__GLIBC__ == 2 && __GLIBC_MINOR__ <= 1) || defined __sun) + if (cd2 != (iconv_t)(-1)) + res2 = iconv (cd2, NULL, NULL, &out2ptr, &out2size); + else +# endif + res2 = 0; + do_final_flush2 = false; + incremented2 = true; + } + + length = out2ptr - result; + grow = (length + extra_alloc > allocated / 2); + if (res2 == (size_t)(-1)) + { + if (errno == E2BIG) + grow = true; + else if (errno == EINVAL) + break; + else if (errno == EILSEQ && handler != iconveh_error) + { + /* Error handling can produce up to 10 bytes of ASCII + output. But TO_CODESET may be UCS-2, UTF-16 or + UCS-4, so use CD2 here as well. */ + char scratchbuf[10]; + size_t scratchlen; + ucs4_t uc; + const char *inptr; + size_t insize; + size_t res; + + if (incremented2) + { + if (u8_prev (&uc, (const uint8_t *) in2ptr, + (const uint8_t *) utf8buf) + == NULL) + abort (); + } + else + { + int n; + if (in2size == 0) + abort (); + n = u8_mbtouc_unsafe (&uc, (const uint8_t *) in2ptr, + in2size); + in2ptr += n; + in2size -= n; + } + + if (handler == iconveh_escape_sequence) + { + static char hex[16] = "0123456789ABCDEF"; + scratchlen = 0; + scratchbuf[scratchlen++] = '\\'; + if (uc < 0x10000) + scratchbuf[scratchlen++] = 'u'; + else + { + scratchbuf[scratchlen++] = 'U'; + scratchbuf[scratchlen++] = hex[(uc>>28) & 15]; + scratchbuf[scratchlen++] = hex[(uc>>24) & 15]; + scratchbuf[scratchlen++] = hex[(uc>>20) & 15]; + scratchbuf[scratchlen++] = hex[(uc>>16) & 15]; + } + scratchbuf[scratchlen++] = hex[(uc>>12) & 15]; + scratchbuf[scratchlen++] = hex[(uc>>8) & 15]; + scratchbuf[scratchlen++] = hex[(uc>>4) & 15]; + scratchbuf[scratchlen++] = hex[uc & 15]; + } + else + { + scratchbuf[0] = '?'; + scratchlen = 1; + } + + inptr = scratchbuf; + insize = scratchlen; + if (cd2 != (iconv_t)(-1)) + res = iconv (cd2, + (ICONV_CONST char **) &inptr, &insize, + &out2ptr, &out2size); + else + { + /* TO_CODESET is UTF-8. */ + if (out2size >= insize) + { + memcpy (out2ptr, inptr, insize); + out2ptr += insize; + out2size -= insize; + inptr += insize; + insize = 0; + res = 0; + } + else + { + errno = E2BIG; + res = (size_t)(-1); + } + } + length = out2ptr - result; + if (res == (size_t)(-1) && errno == E2BIG) + { + char *memory; + + allocated = 2 * allocated; + if (length + 1 + extra_alloc > allocated) + abort (); + if (result == initial_result) + memory = (char *) malloc (allocated); + else + memory = (char *) realloc (result, allocated); + if (memory == NULL) + { + if (result != initial_result) + free (result); + errno = ENOMEM; + return -1; + } + if (result == initial_result) + memcpy (memory, initial_result, length); + result = memory; + grow = false; + + out2ptr = result + length; + out2size = allocated - extra_alloc - length; + if (cd2 != (iconv_t)(-1)) + res = iconv (cd2, + (ICONV_CONST char **) &inptr, + &insize, + &out2ptr, &out2size); + else + { + /* TO_CODESET is UTF-8. */ + if (!(out2size >= insize)) + abort (); + memcpy (out2ptr, inptr, insize); + out2ptr += insize; + out2size -= insize; + inptr += insize; + insize = 0; + res = 0; + } + length = out2ptr - result; + } +# if !defined _LIBICONV_VERSION && !defined __GLIBC__ + /* Irix iconv() inserts a NUL byte if it cannot convert. + NetBSD iconv() inserts a question mark if it cannot + convert. + Only GNU libiconv and GNU libc are known to prefer + to fail rather than doing a lossy conversion. */ + if (res != (size_t)(-1) && res > 0) + { + errno = EILSEQ; + res = (size_t)(-1); + } +# endif + if (res == (size_t)(-1)) + { + /* Failure converting the ASCII replacement. */ + if (result != initial_result) + { + int saved_errno = errno; + free (result); + errno = saved_errno; + } + return -1; + } + } + else + { + if (result != initial_result) + { + int saved_errno = errno; + free (result); + errno = saved_errno; + } + return -1; + } + } + if (!(in2size > 0 + || (in1size == 0 && !do_final_flush1 && do_final_flush2))) + break; + if (grow) + { + char *memory; + + allocated = 2 * allocated; + if (result == initial_result) + memory = (char *) malloc (allocated); + else + memory = (char *) realloc (result, allocated); + if (memory == NULL) + { + if (result != initial_result) + free (result); + errno = ENOMEM; + return -1; + } + if (result == initial_result) + memcpy (memory, initial_result, length); + result = memory; + } + } + + /* Move the remaining bytes to the beginning of utf8buf. */ + if (in2size > 0) + memmove (utf8buf, in2ptr, in2size); + utf8len = in2size; + } + + if (res1 == (size_t)(-1)) + { + if (errno1 == EINVAL) + in1size = 0; + else if (errno1 == EILSEQ) + { + if (result != initial_result) + free (result); + errno = errno1; + return -1; + } + } + } +# undef utf8bufsize + } + + done: + /* Now the final memory allocation. */ + if (result == tmpbuf) + { + size_t memsize = length + extra_alloc; + char *memory; + + memory = (char *) malloc (memsize > 0 ? memsize : 1); + if (memory != NULL) + { + memcpy (memory, tmpbuf, length); + result = memory; + } + else + { + errno = ENOMEM; + return -1; + } + } + else if (result != *resultp && length + extra_alloc < allocated) + { + /* Shrink the allocated memory if possible. */ + size_t memsize = length + extra_alloc; + char *memory; + + memory = (char *) realloc (result, memsize > 0 ? memsize : 1); + if (memory != NULL) + result = memory; + } + *resultp = result; + *lengthp = length; + return 0; +# undef tmpbuf +# undef tmpbufsize +} + +int +mem_cd_iconveh (const char *src, size_t srclen, + iconv_t cd, iconv_t cd1, iconv_t cd2, + enum iconv_ilseq_handler handler, + size_t *offsets, + char **resultp, size_t *lengthp) +{ + return mem_cd_iconveh_internal (src, srclen, cd, cd1, cd2, handler, 0, + offsets, resultp, lengthp); +} + +char * +str_cd_iconveh (const char *src, + iconv_t cd, iconv_t cd1, iconv_t cd2, + enum iconv_ilseq_handler handler) +{ + /* For most encodings, a trailing NUL byte in the input will be converted + to a trailing NUL byte in the output. But not for UTF-7. So that this + function is usable for UTF-7, we have to exclude the NUL byte from the + conversion and add it by hand afterwards. */ + char *result = NULL; + size_t length = 0; + int retval = mem_cd_iconveh_internal (src, strlen (src), + cd, cd1, cd2, handler, 1, NULL, + &result, &length); + + if (retval < 0) + { + if (result != NULL) + { + int saved_errno = errno; + free (result); + errno = saved_errno; + } + return NULL; + } + + /* Add the terminating NUL byte. */ + result[length] = '\0'; + + return result; +} + +#endif + +int +mem_iconveh (const char *src, size_t srclen, + const char *from_codeset, const char *to_codeset, + enum iconv_ilseq_handler handler, + size_t *offsets, + char **resultp, size_t *lengthp) +{ + if (srclen == 0) + { + /* Nothing to convert. */ + *lengthp = 0; + return 0; + } + else if (offsets == NULL && c_strcasecmp (from_codeset, to_codeset) == 0) + { + char *result; + + if (*resultp != NULL && *lengthp >= srclen) + result = *resultp; + else + { + result = (char *) malloc (srclen); + if (result == NULL) + { + errno = ENOMEM; + return -1; + } + } + memcpy (result, src, srclen); + *resultp = result; + *lengthp = srclen; + return 0; + } + else + { +#if HAVE_ICONV + iconv_t cd; + iconv_t cd1; + iconv_t cd2; + char *result; + size_t length; + int retval; + + /* Avoid glibc-2.1 bug with EUC-KR. */ +# if (__GLIBC__ - 0 == 2 && __GLIBC_MINOR__ - 0 <= 1) && !defined _LIBICONV_VERSION + if (c_strcasecmp (from_codeset, "EUC-KR") == 0 + || c_strcasecmp (to_codeset, "EUC-KR") == 0) + { + errno = EINVAL; + return -1; + } +# endif + + cd = iconv_open (to_codeset, from_codeset); + + if (STRCASEEQ (from_codeset, "UTF-8", 'U','T','F','-','8',0,0,0,0)) + cd1 = (iconv_t)(-1); + else + { + cd1 = iconv_open ("UTF-8", from_codeset); + if (cd1 == (iconv_t)(-1)) + { + int saved_errno = errno; + if (cd != (iconv_t)(-1)) + iconv_close (cd); + errno = saved_errno; + return -1; + } + } + + if (STRCASEEQ (to_codeset, "UTF-8", 'U','T','F','-','8',0,0,0,0) +# if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2) || __GLIBC__ > 2 || _LIBICONV_VERSION >= 0x0105 + || c_strcasecmp (to_codeset, "UTF-8//TRANSLIT") == 0 +# endif + ) + cd2 = (iconv_t)(-1); + else + { + cd2 = iconv_open (to_codeset, "UTF-8"); + if (cd2 == (iconv_t)(-1)) + { + int saved_errno = errno; + if (cd1 != (iconv_t)(-1)) + iconv_close (cd1); + if (cd != (iconv_t)(-1)) + iconv_close (cd); + errno = saved_errno; + return -1; + } + } + + result = *resultp; + length = *lengthp; + retval = mem_cd_iconveh (src, srclen, cd, cd1, cd2, handler, offsets, + &result, &length); + + if (retval < 0) + { + /* Close cd, cd1, cd2, but preserve the errno from str_cd_iconv. */ + int saved_errno = errno; + if (cd2 != (iconv_t)(-1)) + iconv_close (cd2); + if (cd1 != (iconv_t)(-1)) + iconv_close (cd1); + if (cd != (iconv_t)(-1)) + iconv_close (cd); + errno = saved_errno; + } + else + { + if (cd2 != (iconv_t)(-1) && iconv_close (cd2) < 0) + { + /* Return -1, but free the allocated memory, and while doing + that, preserve the errno from iconv_close. */ + int saved_errno = errno; + if (cd1 != (iconv_t)(-1)) + iconv_close (cd1); + if (cd != (iconv_t)(-1)) + iconv_close (cd); + if (result != *resultp && result != NULL) + free (result); + errno = saved_errno; + return -1; + } + if (cd1 != (iconv_t)(-1) && iconv_close (cd1) < 0) + { + /* Return -1, but free the allocated memory, and while doing + that, preserve the errno from iconv_close. */ + int saved_errno = errno; + if (cd != (iconv_t)(-1)) + iconv_close (cd); + if (result != *resultp && result != NULL) + free (result); + errno = saved_errno; + return -1; + } + if (cd != (iconv_t)(-1) && iconv_close (cd) < 0) + { + /* Return -1, but free the allocated memory, and while doing + that, preserve the errno from iconv_close. */ + int saved_errno = errno; + if (result != *resultp && result != NULL) + free (result); + errno = saved_errno; + return -1; + } + *resultp = result; + *lengthp = length; + } + return retval; +#else + /* This is a different error code than if iconv_open existed but didn't + support from_codeset and to_codeset, so that the caller can emit + an error message such as + "iconv() is not supported. Installing GNU libiconv and + then reinstalling this package would fix this." */ + errno = ENOSYS; + return -1; +#endif + } +} + +char * +str_iconveh (const char *src, + const char *from_codeset, const char *to_codeset, + enum iconv_ilseq_handler handler) +{ + if (*src == '\0' || c_strcasecmp (from_codeset, to_codeset) == 0) + { + char *result = strdup (src); + + if (result == NULL) + errno = ENOMEM; + return result; + } + else + { +#if HAVE_ICONV + iconv_t cd; + iconv_t cd1; + iconv_t cd2; + char *result; + + /* Avoid glibc-2.1 bug with EUC-KR. */ +# if (__GLIBC__ - 0 == 2 && __GLIBC_MINOR__ - 0 <= 1) && !defined _LIBICONV_VERSION + if (c_strcasecmp (from_codeset, "EUC-KR") == 0 + || c_strcasecmp (to_codeset, "EUC-KR") == 0) + { + errno = EINVAL; + return NULL; + } +# endif + + cd = iconv_open (to_codeset, from_codeset); + + if (STRCASEEQ (from_codeset, "UTF-8", 'U','T','F','-','8',0,0,0,0)) + cd1 = (iconv_t)(-1); + else + { + cd1 = iconv_open ("UTF-8", from_codeset); + if (cd1 == (iconv_t)(-1)) + { + int saved_errno = errno; + if (cd != (iconv_t)(-1)) + iconv_close (cd); + errno = saved_errno; + return NULL; + } + } + + if (STRCASEEQ (to_codeset, "UTF-8", 'U','T','F','-','8',0,0,0,0) +# if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2) || __GLIBC__ > 2 || _LIBICONV_VERSION >= 0x0105 + || c_strcasecmp (to_codeset, "UTF-8//TRANSLIT") == 0 +# endif + ) + cd2 = (iconv_t)(-1); + else + { + cd2 = iconv_open (to_codeset, "UTF-8"); + if (cd2 == (iconv_t)(-1)) + { + int saved_errno = errno; + if (cd1 != (iconv_t)(-1)) + iconv_close (cd1); + if (cd != (iconv_t)(-1)) + iconv_close (cd); + errno = saved_errno; + return NULL; + } + } + + result = str_cd_iconveh (src, cd, cd1, cd2, handler); + + if (result == NULL) + { + /* Close cd, cd1, cd2, but preserve the errno from str_cd_iconv. */ + int saved_errno = errno; + if (cd2 != (iconv_t)(-1)) + iconv_close (cd2); + if (cd1 != (iconv_t)(-1)) + iconv_close (cd1); + if (cd != (iconv_t)(-1)) + iconv_close (cd); + errno = saved_errno; + } + else + { + if (cd2 != (iconv_t)(-1) && iconv_close (cd2) < 0) + { + /* Return NULL, but free the allocated memory, and while doing + that, preserve the errno from iconv_close. */ + int saved_errno = errno; + if (cd1 != (iconv_t)(-1)) + iconv_close (cd1); + if (cd != (iconv_t)(-1)) + iconv_close (cd); + free (result); + errno = saved_errno; + return NULL; + } + if (cd1 != (iconv_t)(-1) && iconv_close (cd1) < 0) + { + /* Return NULL, but free the allocated memory, and while doing + that, preserve the errno from iconv_close. */ + int saved_errno = errno; + if (cd != (iconv_t)(-1)) + iconv_close (cd); + free (result); + errno = saved_errno; + return NULL; + } + if (cd != (iconv_t)(-1) && iconv_close (cd) < 0) + { + /* Return NULL, but free the allocated memory, and while doing + that, preserve the errno from iconv_close. */ + int saved_errno = errno; + free (result); + errno = saved_errno; + return NULL; + } + } + return result; +#else + /* This is a different error code than if iconv_open existed but didn't + support from_codeset and to_codeset, so that the caller can emit + an error message such as + "iconv() is not supported. Installing GNU libiconv and + then reinstalling this package would fix this." */ + errno = ENOSYS; + return NULL; +#endif + } +} diff --git a/lib/striconveh.h b/lib/striconveh.h new file mode 100644 index 000000000..98b4d0c5e --- /dev/null +++ b/lib/striconveh.h @@ -0,0 +1,120 @@ +/* Character set conversion with error handling. + Copyright (C) 2001-2007, 2009 Free Software Foundation, Inc. + Written by Bruno Haible and Simon Josefsson. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#ifndef _STRICONVEH_H +#define _STRICONVEH_H + +#include +#if HAVE_ICONV +#include +#endif + +#include "iconveh.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +#if HAVE_ICONV + +/* Convert an entire string from one encoding to another, using iconv. + The original string is at [SRC,...,SRC+SRCLEN-1]. + CD is the conversion descriptor from FROMCODE to TOCODE, or (iconv_t)(-1) if + the system does not support a direct conversion from FROMCODE to TOCODE. + CD1 is the conversion descriptor from FROM_CODESET to UTF-8 (or + (iconv_t)(-1) if FROM_CODESET is UTF-8). + CD2 is the conversion descriptor from UTF-8 to TO_CODESET (or (iconv_t)(-1) + if TO_CODESET is UTF-8). + If OFFSETS is not NULL, it should point to an array of SRCLEN integers; this + array is filled with offsets into the result, i.e. the character starting + at SRC[i] corresponds to the character starting at (*RESULTP)[OFFSETS[i]], + and other offsets are set to (size_t)(-1). + *RESULTP and *LENGTH should initially be a scratch buffer and its size, + or *RESULTP can initially be NULL. + May erase the contents of the memory at *RESULTP. + Return value: 0 if successful, otherwise -1 and errno set. + If successful: The resulting string is stored in *RESULTP and its length + in *LENGTHP. *RESULTP is set to a freshly allocated memory block, or is + unchanged if no dynamic memory allocation was necessary. */ +extern int + mem_cd_iconveh (const char *src, size_t srclen, + iconv_t cd, iconv_t cd1, iconv_t cd2, + enum iconv_ilseq_handler handler, + size_t *offsets, + char **resultp, size_t *lengthp); + +/* Convert an entire string from one encoding to another, using iconv. + The original string is the NUL-terminated string starting at SRC. + CD is the conversion descriptor from FROMCODE to TOCODE, or (iconv_t)(-1) if + the system does not support a direct conversion from FROMCODE to TOCODE. + Both the "from" and the "to" encoding must use a single NUL byte at the end + of the string (i.e. not UCS-2, UCS-4, UTF-16, UTF-32). + CD1 is the conversion descriptor from FROM_CODESET to UTF-8 (or + (iconv_t)(-1) if FROM_CODESET is UTF-8). + CD2 is the conversion descriptor from UTF-8 to TO_CODESET (or (iconv_t)(-1) + if TO_CODESET is UTF-8). + Allocate a malloced memory block for the result. + Return value: the freshly allocated resulting NUL-terminated string if + successful, otherwise NULL and errno set. */ +extern char * + str_cd_iconveh (const char *src, + iconv_t cd, iconv_t cd1, iconv_t cd2, + enum iconv_ilseq_handler handler); + +#endif + +/* Convert an entire string from one encoding to another, using iconv. + The original string is at [SRC,...,SRC+SRCLEN-1]. + If OFFSETS is not NULL, it should point to an array of SRCLEN integers; this + array is filled with offsets into the result, i.e. the character starting + at SRC[i] corresponds to the character starting at (*RESULTP)[OFFSETS[i]], + and other offsets are set to (size_t)(-1). + *RESULTP and *LENGTH should initially be a scratch buffer and its size, + or *RESULTP can initially be NULL. + May erase the contents of the memory at *RESULTP. + Return value: 0 if successful, otherwise -1 and errno set. + If successful: The resulting string is stored in *RESULTP and its length + in *LENGTHP. *RESULTP is set to a freshly allocated memory block, or is + unchanged if no dynamic memory allocation was necessary. */ +extern int + mem_iconveh (const char *src, size_t srclen, + const char *from_codeset, const char *to_codeset, + enum iconv_ilseq_handler handler, + size_t *offsets, + char **resultp, size_t *lengthp); + +/* Convert an entire string from one encoding to another, using iconv. + The original string is the NUL-terminated string starting at SRC. + Both the "from" and the "to" encoding must use a single NUL byte at the + end of the string (i.e. not UCS-2, UCS-4, UTF-16, UTF-32). + Allocate a malloced memory block for the result. + Return value: the freshly allocated resulting NUL-terminated string if + successful, otherwise NULL and errno set. */ +extern char * + str_iconveh (const char *src, + const char *from_codeset, const char *to_codeset, + enum iconv_ilseq_handler handler); + + +#ifdef __cplusplus +} +#endif + + +#endif /* _STRICONVEH_H */ diff --git a/lib/string.in.h b/lib/string.in.h new file mode 100644 index 000000000..fe1142562 --- /dev/null +++ b/lib/string.in.h @@ -0,0 +1,620 @@ +/* A GNU-like . + + Copyright (C) 1995-1996, 2001-2009 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2, 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef _GL_STRING_H + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif + +/* The include_next requires a split double-inclusion guard. */ +#@INCLUDE_NEXT@ @NEXT_STRING_H@ + +#ifndef _GL_STRING_H +#define _GL_STRING_H + + +#ifndef __attribute__ +/* This feature is available in gcc versions 2.5 and later. */ +# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) +# define __attribute__(Spec) /* empty */ +# endif +/* The attribute __pure__ was added in gcc 2.96. */ +# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 96) +# define __pure__ /* empty */ +# endif +#endif + + +/* The definition of GL_LINK_WARNING is copied here. */ + + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Return the first instance of C within N bytes of S, or NULL. */ +#if @GNULIB_MEMCHR@ +# if @REPLACE_MEMCHR@ +# define memchr rpl_memchr +extern void *memchr (void const *__s, int __c, size_t __n) + __attribute__ ((__pure__)); +# endif +#elif defined GNULIB_POSIXCHECK +# undef memchr +# define memchr(s,c,n) \ + (GL_LINK_WARNING ("memchr has platform-specific bugs - " \ + "use gnulib module memchr for portability" ), \ + memchr (s, c, n)) +#endif + +/* Return the first occurrence of NEEDLE in HAYSTACK. */ +#if @GNULIB_MEMMEM@ +# if @REPLACE_MEMMEM@ +# define memmem rpl_memmem +# endif +# if ! @HAVE_DECL_MEMMEM@ || @REPLACE_MEMMEM@ +extern void *memmem (void const *__haystack, size_t __haystack_len, + void const *__needle, size_t __needle_len) + __attribute__ ((__pure__)); +# endif +#elif defined GNULIB_POSIXCHECK +# undef memmem +# define memmem(a,al,b,bl) \ + (GL_LINK_WARNING ("memmem is unportable and often quadratic - " \ + "use gnulib module memmem-simple for portability, " \ + "and module memmem for speed" ), \ + memmem (a, al, b, bl)) +#endif + +/* Copy N bytes of SRC to DEST, return pointer to bytes after the + last written byte. */ +#if @GNULIB_MEMPCPY@ +# if ! @HAVE_MEMPCPY@ +extern void *mempcpy (void *restrict __dest, void const *restrict __src, + size_t __n); +# endif +#elif defined GNULIB_POSIXCHECK +# undef mempcpy +# define mempcpy(a,b,n) \ + (GL_LINK_WARNING ("mempcpy is unportable - " \ + "use gnulib module mempcpy for portability"), \ + mempcpy (a, b, n)) +#endif + +/* Search backwards through a block for a byte (specified as an int). */ +#if @GNULIB_MEMRCHR@ +# if ! @HAVE_DECL_MEMRCHR@ +extern void *memrchr (void const *, int, size_t) + __attribute__ ((__pure__)); +# endif +#elif defined GNULIB_POSIXCHECK +# undef memrchr +# define memrchr(a,b,c) \ + (GL_LINK_WARNING ("memrchr is unportable - " \ + "use gnulib module memrchr for portability"), \ + memrchr (a, b, c)) +#endif + +/* Find the first occurrence of C in S. More efficient than + memchr(S,C,N), at the expense of undefined behavior if C does not + occur within N bytes. */ +#if @GNULIB_RAWMEMCHR@ +# if ! @HAVE_RAWMEMCHR@ +extern void *rawmemchr (void const *__s, int __c_in) + __attribute__ ((__pure__)); +# endif +#elif defined GNULIB_POSIXCHECK +# undef rawmemchr +# define rawmemchr(a,b) \ + (GL_LINK_WARNING ("rawmemchr is unportable - " \ + "use gnulib module rawmemchr for portability"), \ + rawmemchr (a, b)) +#endif + +/* Copy SRC to DST, returning the address of the terminating '\0' in DST. */ +#if @GNULIB_STPCPY@ +# if ! @HAVE_STPCPY@ +extern char *stpcpy (char *restrict __dst, char const *restrict __src); +# endif +#elif defined GNULIB_POSIXCHECK +# undef stpcpy +# define stpcpy(a,b) \ + (GL_LINK_WARNING ("stpcpy is unportable - " \ + "use gnulib module stpcpy for portability"), \ + stpcpy (a, b)) +#endif + +/* Copy no more than N bytes of SRC to DST, returning a pointer past the + last non-NUL byte written into DST. */ +#if @GNULIB_STPNCPY@ +# if ! @HAVE_STPNCPY@ +# define stpncpy gnu_stpncpy +extern char *stpncpy (char *restrict __dst, char const *restrict __src, + size_t __n); +# endif +#elif defined GNULIB_POSIXCHECK +# undef stpncpy +# define stpncpy(a,b,n) \ + (GL_LINK_WARNING ("stpncpy is unportable - " \ + "use gnulib module stpncpy for portability"), \ + stpncpy (a, b, n)) +#endif + +#if defined GNULIB_POSIXCHECK +/* strchr() does not work with multibyte strings if the locale encoding is + GB18030 and the character to be searched is a digit. */ +# undef strchr +# define strchr(s,c) \ + (GL_LINK_WARNING ("strchr cannot work correctly on character strings " \ + "in some multibyte locales - " \ + "use mbschr if you care about internationalization"), \ + strchr (s, c)) +#endif + +/* Find the first occurrence of C in S or the final NUL byte. */ +#if @GNULIB_STRCHRNUL@ +# if ! @HAVE_STRCHRNUL@ +extern char *strchrnul (char const *__s, int __c_in) + __attribute__ ((__pure__)); +# endif +#elif defined GNULIB_POSIXCHECK +# undef strchrnul +# define strchrnul(a,b) \ + (GL_LINK_WARNING ("strchrnul is unportable - " \ + "use gnulib module strchrnul for portability"), \ + strchrnul (a, b)) +#endif + +/* Duplicate S, returning an identical malloc'd string. */ +#if @GNULIB_STRDUP@ +# if @REPLACE_STRDUP@ +# undef strdup +# define strdup rpl_strdup +# endif +# if !(@HAVE_DECL_STRDUP@ || defined strdup) || @REPLACE_STRDUP@ +extern char *strdup (char const *__s); +# endif +#elif defined GNULIB_POSIXCHECK +# undef strdup +# define strdup(a) \ + (GL_LINK_WARNING ("strdup is unportable - " \ + "use gnulib module strdup for portability"), \ + strdup (a)) +#endif + +/* Return a newly allocated copy of at most N bytes of STRING. */ +#if @GNULIB_STRNDUP@ +# if ! @HAVE_STRNDUP@ +# undef strndup +# define strndup rpl_strndup +# endif +# if ! @HAVE_STRNDUP@ || ! @HAVE_DECL_STRNDUP@ +extern char *strndup (char const *__string, size_t __n); +# endif +#elif defined GNULIB_POSIXCHECK +# undef strndup +# define strndup(a,n) \ + (GL_LINK_WARNING ("strndup is unportable - " \ + "use gnulib module strndup for portability"), \ + strndup (a, n)) +#endif + +/* Find the length (number of bytes) of STRING, but scan at most + MAXLEN bytes. If no '\0' terminator is found in that many bytes, + return MAXLEN. */ +#if @GNULIB_STRNLEN@ +# if ! @HAVE_DECL_STRNLEN@ +extern size_t strnlen (char const *__string, size_t __maxlen) + __attribute__ ((__pure__)); +# endif +#elif defined GNULIB_POSIXCHECK +# undef strnlen +# define strnlen(a,n) \ + (GL_LINK_WARNING ("strnlen is unportable - " \ + "use gnulib module strnlen for portability"), \ + strnlen (a, n)) +#endif + +#if defined GNULIB_POSIXCHECK +/* strcspn() assumes the second argument is a list of single-byte characters. + Even in this simple case, it does not work with multibyte strings if the + locale encoding is GB18030 and one of the characters to be searched is a + digit. */ +# undef strcspn +# define strcspn(s,a) \ + (GL_LINK_WARNING ("strcspn cannot work correctly on character strings " \ + "in multibyte locales - " \ + "use mbscspn if you care about internationalization"), \ + strcspn (s, a)) +#endif + +/* Find the first occurrence in S of any character in ACCEPT. */ +#if @GNULIB_STRPBRK@ +# if ! @HAVE_STRPBRK@ +extern char *strpbrk (char const *__s, char const *__accept) + __attribute__ ((__pure__)); +# endif +# if defined GNULIB_POSIXCHECK +/* strpbrk() assumes the second argument is a list of single-byte characters. + Even in this simple case, it does not work with multibyte strings if the + locale encoding is GB18030 and one of the characters to be searched is a + digit. */ +# undef strpbrk +# define strpbrk(s,a) \ + (GL_LINK_WARNING ("strpbrk cannot work correctly on character strings " \ + "in multibyte locales - " \ + "use mbspbrk if you care about internationalization"), \ + strpbrk (s, a)) +# endif +#elif defined GNULIB_POSIXCHECK +# undef strpbrk +# define strpbrk(s,a) \ + (GL_LINK_WARNING ("strpbrk is unportable - " \ + "use gnulib module strpbrk for portability"), \ + strpbrk (s, a)) +#endif + +#if defined GNULIB_POSIXCHECK +/* strspn() assumes the second argument is a list of single-byte characters. + Even in this simple case, it cannot work with multibyte strings. */ +# undef strspn +# define strspn(s,a) \ + (GL_LINK_WARNING ("strspn cannot work correctly on character strings " \ + "in multibyte locales - " \ + "use mbsspn if you care about internationalization"), \ + strspn (s, a)) +#endif + +#if defined GNULIB_POSIXCHECK +/* strrchr() does not work with multibyte strings if the locale encoding is + GB18030 and the character to be searched is a digit. */ +# undef strrchr +# define strrchr(s,c) \ + (GL_LINK_WARNING ("strrchr cannot work correctly on character strings " \ + "in some multibyte locales - " \ + "use mbsrchr if you care about internationalization"), \ + strrchr (s, c)) +#endif + +/* Search the next delimiter (char listed in DELIM) starting at *STRINGP. + If one is found, overwrite it with a NUL, and advance *STRINGP + to point to the next char after it. Otherwise, set *STRINGP to NULL. + If *STRINGP was already NULL, nothing happens. + Return the old value of *STRINGP. + + This is a variant of strtok() that is multithread-safe and supports + empty fields. + + Caveat: It modifies the original string. + Caveat: These functions cannot be used on constant strings. + Caveat: The identity of the delimiting character is lost. + Caveat: It doesn't work with multibyte strings unless all of the delimiter + characters are ASCII characters < 0x30. + + See also strtok_r(). */ +#if @GNULIB_STRSEP@ +# if ! @HAVE_STRSEP@ +extern char *strsep (char **restrict __stringp, char const *restrict __delim); +# endif +# if defined GNULIB_POSIXCHECK +# undef strsep +# define strsep(s,d) \ + (GL_LINK_WARNING ("strsep cannot work correctly on character strings " \ + "in multibyte locales - " \ + "use mbssep if you care about internationalization"), \ + strsep (s, d)) +# endif +#elif defined GNULIB_POSIXCHECK +# undef strsep +# define strsep(s,d) \ + (GL_LINK_WARNING ("strsep is unportable - " \ + "use gnulib module strsep for portability"), \ + strsep (s, d)) +#endif + +#if @GNULIB_STRSTR@ +# if @REPLACE_STRSTR@ +# define strstr rpl_strstr +char *strstr (const char *haystack, const char *needle) + __attribute__ ((__pure__)); +# endif +#elif defined GNULIB_POSIXCHECK +/* strstr() does not work with multibyte strings if the locale encoding is + different from UTF-8: + POSIX says that it operates on "strings", and "string" in POSIX is defined + as a sequence of bytes, not of characters. */ +# undef strstr +# define strstr(a,b) \ + (GL_LINK_WARNING ("strstr is quadratic on many systems, and cannot " \ + "work correctly on character strings in most " \ + "multibyte locales - " \ + "use mbsstr if you care about internationalization, " \ + "or use strstr if you care about speed"), \ + strstr (a, b)) +#endif + +/* Find the first occurrence of NEEDLE in HAYSTACK, using case-insensitive + comparison. */ +#if @GNULIB_STRCASESTR@ +# if @REPLACE_STRCASESTR@ +# define strcasestr rpl_strcasestr +# endif +# if ! @HAVE_STRCASESTR@ || @REPLACE_STRCASESTR@ +extern char *strcasestr (const char *haystack, const char *needle) + __attribute__ ((__pure__)); +# endif +#elif defined GNULIB_POSIXCHECK +/* strcasestr() does not work with multibyte strings: + It is a glibc extension, and glibc implements it only for unibyte + locales. */ +# undef strcasestr +# define strcasestr(a,b) \ + (GL_LINK_WARNING ("strcasestr does work correctly on character strings " \ + "in multibyte locales - " \ + "use mbscasestr if you care about " \ + "internationalization, or use c-strcasestr if you want " \ + "a locale independent function"), \ + strcasestr (a, b)) +#endif + +/* Parse S into tokens separated by characters in DELIM. + If S is NULL, the saved pointer in SAVE_PTR is used as + the next starting point. For example: + char s[] = "-abc-=-def"; + char *sp; + x = strtok_r(s, "-", &sp); // x = "abc", sp = "=-def" + x = strtok_r(NULL, "-=", &sp); // x = "def", sp = NULL + x = strtok_r(NULL, "=", &sp); // x = NULL + // s = "abc\0-def\0" + + This is a variant of strtok() that is multithread-safe. + + For the POSIX documentation for this function, see: + http://www.opengroup.org/susv3xsh/strtok.html + + Caveat: It modifies the original string. + Caveat: These functions cannot be used on constant strings. + Caveat: The identity of the delimiting character is lost. + Caveat: It doesn't work with multibyte strings unless all of the delimiter + characters are ASCII characters < 0x30. + + See also strsep(). */ +#if @GNULIB_STRTOK_R@ +# if ! @HAVE_DECL_STRTOK_R@ +extern char *strtok_r (char *restrict s, char const *restrict delim, + char **restrict save_ptr); +# endif +# if defined GNULIB_POSIXCHECK +# undef strtok_r +# define strtok_r(s,d,p) \ + (GL_LINK_WARNING ("strtok_r cannot work correctly on character strings " \ + "in multibyte locales - " \ + "use mbstok_r if you care about internationalization"), \ + strtok_r (s, d, p)) +# endif +#elif defined GNULIB_POSIXCHECK +# undef strtok_r +# define strtok_r(s,d,p) \ + (GL_LINK_WARNING ("strtok_r is unportable - " \ + "use gnulib module strtok_r for portability"), \ + strtok_r (s, d, p)) +#endif + + +/* The following functions are not specified by POSIX. They are gnulib + extensions. */ + +#if @GNULIB_MBSLEN@ +/* Return the number of multibyte characters in the character string STRING. + This considers multibyte characters, unlike strlen, which counts bytes. */ +extern size_t mbslen (const char *string); +#endif + +#if @GNULIB_MBSNLEN@ +/* Return the number of multibyte characters in the character string starting + at STRING and ending at STRING + LEN. */ +extern size_t mbsnlen (const char *string, size_t len); +#endif + +#if @GNULIB_MBSCHR@ +/* Locate the first single-byte character C in the character string STRING, + and return a pointer to it. Return NULL if C is not found in STRING. + Unlike strchr(), this function works correctly in multibyte locales with + encodings such as GB18030. */ +# define mbschr rpl_mbschr /* avoid collision with HP-UX function */ +extern char * mbschr (const char *string, int c); +#endif + +#if @GNULIB_MBSRCHR@ +/* Locate the last single-byte character C in the character string STRING, + and return a pointer to it. Return NULL if C is not found in STRING. + Unlike strrchr(), this function works correctly in multibyte locales with + encodings such as GB18030. */ +# define mbsrchr rpl_mbsrchr /* avoid collision with HP-UX function */ +extern char * mbsrchr (const char *string, int c); +#endif + +#if @GNULIB_MBSSTR@ +/* Find the first occurrence of the character string NEEDLE in the character + string HAYSTACK. Return NULL if NEEDLE is not found in HAYSTACK. + Unlike strstr(), this function works correctly in multibyte locales with + encodings different from UTF-8. */ +extern char * mbsstr (const char *haystack, const char *needle); +#endif + +#if @GNULIB_MBSCASECMP@ +/* Compare the character strings S1 and S2, ignoring case, returning less than, + equal to or greater than zero if S1 is lexicographically less than, equal to + or greater than S2. + Note: This function may, in multibyte locales, return 0 for strings of + different lengths! + Unlike strcasecmp(), this function works correctly in multibyte locales. */ +extern int mbscasecmp (const char *s1, const char *s2); +#endif + +#if @GNULIB_MBSNCASECMP@ +/* Compare the initial segment of the character string S1 consisting of at most + N characters with the initial segment of the character string S2 consisting + of at most N characters, ignoring case, returning less than, equal to or + greater than zero if the initial segment of S1 is lexicographically less + than, equal to or greater than the initial segment of S2. + Note: This function may, in multibyte locales, return 0 for initial segments + of different lengths! + Unlike strncasecmp(), this function works correctly in multibyte locales. + But beware that N is not a byte count but a character count! */ +extern int mbsncasecmp (const char *s1, const char *s2, size_t n); +#endif + +#if @GNULIB_MBSPCASECMP@ +/* Compare the initial segment of the character string STRING consisting of + at most mbslen (PREFIX) characters with the character string PREFIX, + ignoring case, returning less than, equal to or greater than zero if this + initial segment is lexicographically less than, equal to or greater than + PREFIX. + Note: This function may, in multibyte locales, return 0 if STRING is of + smaller length than PREFIX! + Unlike strncasecmp(), this function works correctly in multibyte + locales. */ +extern char * mbspcasecmp (const char *string, const char *prefix); +#endif + +#if @GNULIB_MBSCASESTR@ +/* Find the first occurrence of the character string NEEDLE in the character + string HAYSTACK, using case-insensitive comparison. + Note: This function may, in multibyte locales, return success even if + strlen (haystack) < strlen (needle) ! + Unlike strcasestr(), this function works correctly in multibyte locales. */ +extern char * mbscasestr (const char *haystack, const char *needle); +#endif + +#if @GNULIB_MBSCSPN@ +/* Find the first occurrence in the character string STRING of any character + in the character string ACCEPT. Return the number of bytes from the + beginning of the string to this occurrence, or to the end of the string + if none exists. + Unlike strcspn(), this function works correctly in multibyte locales. */ +extern size_t mbscspn (const char *string, const char *accept); +#endif + +#if @GNULIB_MBSPBRK@ +/* Find the first occurrence in the character string STRING of any character + in the character string ACCEPT. Return the pointer to it, or NULL if none + exists. + Unlike strpbrk(), this function works correctly in multibyte locales. */ +# define mbspbrk rpl_mbspbrk /* avoid collision with HP-UX function */ +extern char * mbspbrk (const char *string, const char *accept); +#endif + +#if @GNULIB_MBSSPN@ +/* Find the first occurrence in the character string STRING of any character + not in the character string REJECT. Return the number of bytes from the + beginning of the string to this occurrence, or to the end of the string + if none exists. + Unlike strspn(), this function works correctly in multibyte locales. */ +extern size_t mbsspn (const char *string, const char *reject); +#endif + +#if @GNULIB_MBSSEP@ +/* Search the next delimiter (multibyte character listed in the character + string DELIM) starting at the character string *STRINGP. + If one is found, overwrite it with a NUL, and advance *STRINGP to point + to the next multibyte character after it. Otherwise, set *STRINGP to NULL. + If *STRINGP was already NULL, nothing happens. + Return the old value of *STRINGP. + + This is a variant of mbstok_r() that supports empty fields. + + Caveat: It modifies the original string. + Caveat: These functions cannot be used on constant strings. + Caveat: The identity of the delimiting character is lost. + + See also mbstok_r(). */ +extern char * mbssep (char **stringp, const char *delim); +#endif + +#if @GNULIB_MBSTOK_R@ +/* Parse the character string STRING into tokens separated by characters in + the character string DELIM. + If STRING is NULL, the saved pointer in SAVE_PTR is used as + the next starting point. For example: + char s[] = "-abc-=-def"; + char *sp; + x = mbstok_r(s, "-", &sp); // x = "abc", sp = "=-def" + x = mbstok_r(NULL, "-=", &sp); // x = "def", sp = NULL + x = mbstok_r(NULL, "=", &sp); // x = NULL + // s = "abc\0-def\0" + + Caveat: It modifies the original string. + Caveat: These functions cannot be used on constant strings. + Caveat: The identity of the delimiting character is lost. + + See also mbssep(). */ +extern char * mbstok_r (char *string, const char *delim, char **save_ptr); +#endif + +/* Map any int, typically from errno, into an error message. */ +#if @GNULIB_STRERROR@ +# if @REPLACE_STRERROR@ +# undef strerror +# define strerror rpl_strerror +extern char *strerror (int); +# endif +#elif defined GNULIB_POSIXCHECK +# undef strerror +# define strerror(e) \ + (GL_LINK_WARNING ("strerror is unportable - " \ + "use gnulib module strerror to guarantee non-NULL result"), \ + strerror (e)) +#endif + +#if @GNULIB_STRSIGNAL@ +# if @REPLACE_STRSIGNAL@ +# define strsignal rpl_strsignal +# endif +# if ! @HAVE_DECL_STRSIGNAL@ || @REPLACE_STRSIGNAL@ +extern char *strsignal (int __sig); +# endif +#elif defined GNULIB_POSIXCHECK +# undef strsignal +# define strsignal(a) \ + (GL_LINK_WARNING ("strsignal is unportable - " \ + "use gnulib module strsignal for portability"), \ + strsignal (a)) +#endif + +#if @GNULIB_STRVERSCMP@ +# if !@HAVE_STRVERSCMP@ +extern int strverscmp (const char *, const char *); +# endif +#elif defined GNULIB_POSIXCHECK +# undef strverscmp +# define strverscmp(a, b) \ + (GL_LINK_WARNING ("strverscmp is unportable - " \ + "use gnulib module strverscmp for portability"), \ + strverscmp (a, b)) +#endif + + +#ifdef __cplusplus +} +#endif + +#endif /* _GL_STRING_H */ +#endif /* _GL_STRING_H */ diff --git a/lib/sys_file.in.h b/lib/sys_file.in.h new file mode 100644 index 000000000..52ef46619 --- /dev/null +++ b/lib/sys_file.in.h @@ -0,0 +1,60 @@ +/* Provide a more complete sys/file.h. + + Copyright (C) 2007-2008 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2, 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* Written by Richard W.M. Jones. */ +#ifndef _GL_SYS_FILE_H + +# if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +# endif + +/* The include_next requires a split double-inclusion guard. */ +# if @HAVE_SYS_FILE_H@ +# @INCLUDE_NEXT@ @NEXT_SYS_FILE_H@ +# endif + +#ifndef _GL_SYS_FILE_H +#define _GL_SYS_FILE_H + + +#if @GNULIB_FLOCK@ +/* Apply or remove advisory locks on an open file. + Return 0 if successful, otherwise -1 and errno set. */ +# if !@HAVE_FLOCK@ +extern int flock (int fd, int operation); + +/* Operations for the 'flock' call (same as Linux kernel constants). */ +#define LOCK_SH 1 /* Shared lock. */ +#define LOCK_EX 2 /* Exclusive lock. */ +#define LOCK_UN 8 /* Unlock. */ + +/* Can be OR'd in to one of the above. */ +#define LOCK_NB 4 /* Don't block when locking. */ + +# endif +#elif defined GNULIB_POSIXCHECK +# undef flock +# define flock(fd,op) \ + (GL_LINK_WARNING ("flock is unportable - " \ + "use gnulib module flock for portability"), \ + flock ((fd), (op))) +#endif + + +#endif /* _GL_SYS_FILE_H */ +#endif /* _GL_SYS_FILE_H */ diff --git a/lib/time.in.h b/lib/time.in.h index 7da429a54..cef4e0546 100644 --- a/lib/time.in.h +++ b/lib/time.in.h @@ -1,6 +1,6 @@ /* A more-standard . - Copyright (C) 2007-2008 Free Software Foundation, Inc. + Copyright (C) 2007-2009 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by @@ -66,6 +66,12 @@ struct timespec int nanosleep (struct timespec const *__rqtp, struct timespec *__rmtp); # endif +/* Return the 'time_t' representation of TP and normalize TP. */ +# if @REPLACE_MKTIME@ +# define mktime rpl_mktime +extern time_t mktime (struct tm *__tp); +# endif + /* Convert TIMER to RESULT, assuming local time and UTC respectively. See and . */ diff --git a/lib/unistd.in.h b/lib/unistd.in.h index d4b842a05..e2545cbca 100644 --- a/lib/unistd.in.h +++ b/lib/unistd.in.h @@ -1,5 +1,5 @@ /* Substitute for and wrapper around . - Copyright (C) 2003-2008 Free Software Foundation, Inc. + Copyright (C) 2003-2009 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by @@ -29,7 +29,7 @@ #ifndef _GL_UNISTD_H #define _GL_UNISTD_H -/* mingw doesn't define the SEEK_* macros in . */ +/* mingw doesn't define the SEEK_* or *_FILENO macros in . */ #if !(defined SEEK_CUR && defined SEEK_END && defined SEEK_SET) # include #endif @@ -87,6 +87,17 @@ /* The definition of GL_LINK_WARNING is copied here. */ +/* OS/2 EMX lacks these macros. */ +#ifndef STDIN_FILENO +# define STDIN_FILENO 0 +#endif +#ifndef STDOUT_FILENO +# define STDOUT_FILENO 1 +#endif +#ifndef STDERR_FILENO +# define STDERR_FILENO 2 +#endif + /* Declare overridden functions. */ #ifdef __cplusplus @@ -120,10 +131,6 @@ extern int chown (const char *file, uid_t uid, gid_t gid); #if @GNULIB_CLOSE@ -# if @UNISTD_H_HAVE_WINSOCK2_H@ -/* Need a gnulib internal function. */ -# define HAVE__GL_CLOSE_FD_MAYBE_SOCKET 1 -# endif # if @REPLACE_CLOSE@ /* Automatically included by modules that need a replacement for close. */ # undef close @@ -143,10 +150,13 @@ extern int close (int); #if @GNULIB_DUP2@ -# if !@HAVE_DUP2@ +# if @REPLACE_DUP2@ +# define dup2 rpl_dup2 +# endif +# if !@HAVE_DUP2@ || @REPLACE_DUP2@ /* Copy the file descriptor OLDFD into file descriptor NEWFD. Do nothing if NEWFD = OLDFD, otherwise close NEWFD first if it is open. - Return 0 if successful, otherwise -1 and errno set. + Return newfd if successful, otherwise -1 and errno set. See the POSIX:2001 specification . */ extern int dup2 (int oldfd, int newfd); @@ -207,7 +217,11 @@ extern int fchdir (int /*fd*/); # define dup rpl_dup extern int dup (int); -# define dup2 rpl_dup2 + +# if @REPLACE_DUP2@ +# undef dup2 +# endif +# define dup2 rpl_dup2_fchdir extern int dup2 (int, int); # endif @@ -475,6 +489,23 @@ extern int lchown (char const *file, uid_t owner, gid_t group); #endif +#if @GNULIB_LINK@ +/* Create a new hard link for an existing file. + Return 0 if successful, otherwise -1 and errno set. + See POSIX:2001 specification + . */ +# if !@HAVE_LINK@ +extern int link (const char *path1, const char *path2); +# endif +#elif defined GNULIB_POSIXCHECK +# undef link +# define link(path1,path2) \ + (GL_LINK_WARNING ("link is unportable - " \ + "use gnulib module link for portability"), \ + link (path1, path2)) +#endif + + #if @GNULIB_LSEEK@ # if @REPLACE_LSEEK@ /* Set the offset of FD relative to SEEK_SET, SEEK_CUR, or SEEK_END. diff --git a/lib/unistr.h b/lib/unistr.h new file mode 100644 index 000000000..83ff13411 --- /dev/null +++ b/lib/unistr.h @@ -0,0 +1,681 @@ +/* Elementary Unicode string functions. + Copyright (C) 2001-2002, 2005-2009 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#ifndef _UNISTR_H +#define _UNISTR_H + +#include "unitypes.h" + +/* Get bool. */ +#include + +/* Get size_t. */ +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Conventions: + + All functions prefixed with u8_ operate on UTF-8 encoded strings. + Their unit is an uint8_t (1 byte). + + All functions prefixed with u16_ operate on UTF-16 encoded strings. + Their unit is an uint16_t (a 2-byte word). + + All functions prefixed with u32_ operate on UCS-4 encoded strings. + Their unit is an uint32_t (a 4-byte word). + + All argument pairs (s, n) denote a Unicode string s[0..n-1] with exactly + n units. + + All arguments starting with "str" and the arguments of functions starting + with u8_str/u16_str/u32_str denote a NUL terminated string, i.e. a string + which terminates at the first NUL unit. This termination unit is + considered part of the string for all memory allocation purposes, but + is not considered part of the string for all other logical purposes. + + Functions returning a string result take a (resultbuf, lengthp) argument + pair. If resultbuf is not NULL and the result fits into *lengthp units, + it is put in resultbuf, and resultbuf is returned. Otherwise, a freshly + allocated string is returned. In both cases, *lengthp is set to the + length (number of units) of the returned string. In case of error, + NULL is returned and errno is set. */ + + +/* Elementary string checks. */ + +/* Check whether an UTF-8 string is well-formed. + Return NULL if valid, or a pointer to the first invalid unit otherwise. */ +extern const uint8_t * + u8_check (const uint8_t *s, size_t n); + +/* Check whether an UTF-16 string is well-formed. + Return NULL if valid, or a pointer to the first invalid unit otherwise. */ +extern const uint16_t * + u16_check (const uint16_t *s, size_t n); + +/* Check whether an UCS-4 string is well-formed. + Return NULL if valid, or a pointer to the first invalid unit otherwise. */ +extern const uint32_t * + u32_check (const uint32_t *s, size_t n); + + +/* Elementary string conversions. */ + +/* Convert an UTF-8 string to an UTF-16 string. */ +extern uint16_t * + u8_to_u16 (const uint8_t *s, size_t n, uint16_t *resultbuf, + size_t *lengthp); + +/* Convert an UTF-8 string to an UCS-4 string. */ +extern uint32_t * + u8_to_u32 (const uint8_t *s, size_t n, uint32_t *resultbuf, + size_t *lengthp); + +/* Convert an UTF-16 string to an UTF-8 string. */ +extern uint8_t * + u16_to_u8 (const uint16_t *s, size_t n, uint8_t *resultbuf, + size_t *lengthp); + +/* Convert an UTF-16 string to an UCS-4 string. */ +extern uint32_t * + u16_to_u32 (const uint16_t *s, size_t n, uint32_t *resultbuf, + size_t *lengthp); + +/* Convert an UCS-4 string to an UTF-8 string. */ +extern uint8_t * + u32_to_u8 (const uint32_t *s, size_t n, uint8_t *resultbuf, + size_t *lengthp); + +/* Convert an UCS-4 string to an UTF-16 string. */ +extern uint16_t * + u32_to_u16 (const uint32_t *s, size_t n, uint16_t *resultbuf, + size_t *lengthp); + + +/* Elementary string functions. */ + +/* Return the length (number of units) of the first character in S, which is + no longer than N. Return 0 if it is the NUL character. Return -1 upon + failure. */ +/* Similar to mblen(), except that s must not be NULL. */ +extern int + u8_mblen (const uint8_t *s, size_t n); +extern int + u16_mblen (const uint16_t *s, size_t n); +extern int + u32_mblen (const uint32_t *s, size_t n); + +/* Return the length (number of units) of the first character in S, putting + its 'ucs4_t' representation in *PUC. Upon failure, *PUC is set to 0xfffd, + and an appropriate number of units is returned. + The number of available units, N, must be > 0. */ +/* Similar to mbtowc(), except that puc and s must not be NULL, n must be > 0, + and the NUL character is not treated specially. */ +/* The variants with _safe suffix are safe, even if the library is compiled + without --enable-safety. */ + +#ifdef GNULIB_UNISTR_U8_MBTOUC_UNSAFE +# if !HAVE_INLINE +extern int + u8_mbtouc_unsafe (ucs4_t *puc, const uint8_t *s, size_t n); +# else +extern int + u8_mbtouc_unsafe_aux (ucs4_t *puc, const uint8_t *s, size_t n); +static inline int +u8_mbtouc_unsafe (ucs4_t *puc, const uint8_t *s, size_t n) +{ + uint8_t c = *s; + + if (c < 0x80) + { + *puc = c; + return 1; + } + else + return u8_mbtouc_unsafe_aux (puc, s, n); +} +# endif +#endif + +#ifdef GNULIB_UNISTR_U16_MBTOUC_UNSAFE +# if !HAVE_INLINE +extern int + u16_mbtouc_unsafe (ucs4_t *puc, const uint16_t *s, size_t n); +# else +extern int + u16_mbtouc_unsafe_aux (ucs4_t *puc, const uint16_t *s, size_t n); +static inline int +u16_mbtouc_unsafe (ucs4_t *puc, const uint16_t *s, size_t n) +{ + uint16_t c = *s; + + if (c < 0xd800 || c >= 0xe000) + { + *puc = c; + return 1; + } + else + return u16_mbtouc_unsafe_aux (puc, s, n); +} +# endif +#endif + +#ifdef GNULIB_UNISTR_U32_MBTOUC_UNSAFE +# if !HAVE_INLINE +extern int + u32_mbtouc_unsafe (ucs4_t *puc, const uint32_t *s, size_t n); +# else +static inline int +u32_mbtouc_unsafe (ucs4_t *puc, const uint32_t *s, size_t n _UNUSED_PARAMETER_) +{ + uint32_t c = *s; + +# if CONFIG_UNICODE_SAFETY + if (c < 0xd800 || (c >= 0xe000 && c < 0x110000)) +# endif + *puc = c; +# if CONFIG_UNICODE_SAFETY + else + /* invalid multibyte character */ + *puc = 0xfffd; +# endif + return 1; +} +# endif +#endif + +#ifdef GNULIB_UNISTR_U8_MBTOUC +# if !HAVE_INLINE +extern int + u8_mbtouc (ucs4_t *puc, const uint8_t *s, size_t n); +# else +extern int + u8_mbtouc_aux (ucs4_t *puc, const uint8_t *s, size_t n); +static inline int +u8_mbtouc (ucs4_t *puc, const uint8_t *s, size_t n) +{ + uint8_t c = *s; + + if (c < 0x80) + { + *puc = c; + return 1; + } + else + return u8_mbtouc_aux (puc, s, n); +} +# endif +#endif + +#ifdef GNULIB_UNISTR_U16_MBTOUC +# if !HAVE_INLINE +extern int + u16_mbtouc (ucs4_t *puc, const uint16_t *s, size_t n); +# else +extern int + u16_mbtouc_aux (ucs4_t *puc, const uint16_t *s, size_t n); +static inline int +u16_mbtouc (ucs4_t *puc, const uint16_t *s, size_t n) +{ + uint16_t c = *s; + + if (c < 0xd800 || c >= 0xe000) + { + *puc = c; + return 1; + } + else + return u16_mbtouc_aux (puc, s, n); +} +# endif +#endif + +#ifdef GNULIB_UNISTR_U32_MBTOUC +# if !HAVE_INLINE +extern int + u32_mbtouc (ucs4_t *puc, const uint32_t *s, size_t n); +# else +static inline int +u32_mbtouc (ucs4_t *puc, const uint32_t *s, size_t n _UNUSED_PARAMETER_) +{ + uint32_t c = *s; + + if (c < 0xd800 || (c >= 0xe000 && c < 0x110000)) + *puc = c; + else + /* invalid multibyte character */ + *puc = 0xfffd; + return 1; +} +# endif +#endif + +/* Return the length (number of units) of the first character in S, putting + its 'ucs4_t' representation in *PUC. Upon failure, *PUC is set to 0xfffd, + and -1 is returned for an invalid sequence of units, -2 is returned for an + incomplete sequence of units. + The number of available units, N, must be > 0. */ +/* Similar to u*_mbtouc(), except that the return value gives more details + about the failure, similar to mbrtowc(). */ + +#ifdef GNULIB_UNISTR_U8_MBTOUCR +extern int + u8_mbtoucr (ucs4_t *puc, const uint8_t *s, size_t n); +#endif + +#ifdef GNULIB_UNISTR_U16_MBTOUCR +extern int + u16_mbtoucr (ucs4_t *puc, const uint16_t *s, size_t n); +#endif + +#ifdef GNULIB_UNISTR_U32_MBTOUCR +extern int + u32_mbtoucr (ucs4_t *puc, const uint32_t *s, size_t n); +#endif + +/* Put the multibyte character represented by UC in S, returning its + length. Return -1 upon failure, -2 if the number of available units, N, + is too small. The latter case cannot occur if N >= 6/2/1, respectively. */ +/* Similar to wctomb(), except that s must not be NULL, and the argument n + must be specified. */ + +#ifdef GNULIB_UNISTR_U8_UCTOMB +/* Auxiliary function, also used by u8_chr, u8_strchr, u8_strrchr. */ +extern int + u8_uctomb_aux (uint8_t *s, ucs4_t uc, int n); +# if !HAVE_INLINE +extern int + u8_uctomb (uint8_t *s, ucs4_t uc, int n); +# else +static inline int +u8_uctomb (uint8_t *s, ucs4_t uc, int n) +{ + if (uc < 0x80 && n > 0) + { + s[0] = uc; + return 1; + } + else + return u8_uctomb_aux (s, uc, n); +} +# endif +#endif + +#ifdef GNULIB_UNISTR_U16_UCTOMB +/* Auxiliary function, also used by u16_chr, u16_strchr, u16_strrchr. */ +extern int + u16_uctomb_aux (uint16_t *s, ucs4_t uc, int n); +# if !HAVE_INLINE +extern int + u16_uctomb (uint16_t *s, ucs4_t uc, int n); +# else +static inline int +u16_uctomb (uint16_t *s, ucs4_t uc, int n) +{ + if (uc < 0xd800 && n > 0) + { + s[0] = uc; + return 1; + } + else + return u16_uctomb_aux (s, uc, n); +} +# endif +#endif + +#ifdef GNULIB_UNISTR_U32_UCTOMB +# if !HAVE_INLINE +extern int + u32_uctomb (uint32_t *s, ucs4_t uc, int n); +# else +static inline int +u32_uctomb (uint32_t *s, ucs4_t uc, int n) +{ + if (uc < 0xd800 || (uc >= 0xe000 && uc < 0x110000)) + { + if (n > 0) + { + *s = uc; + return 1; + } + else + return -2; + } + else + return -1; +} +# endif +#endif + +/* Copy N units from SRC to DEST. */ +/* Similar to memcpy(). */ +extern uint8_t * + u8_cpy (uint8_t *dest, const uint8_t *src, size_t n); +extern uint16_t * + u16_cpy (uint16_t *dest, const uint16_t *src, size_t n); +extern uint32_t * + u32_cpy (uint32_t *dest, const uint32_t *src, size_t n); + +/* Copy N units from SRC to DEST, guaranteeing correct behavior for + overlapping memory areas. */ +/* Similar to memmove(). */ +extern uint8_t * + u8_move (uint8_t *dest, const uint8_t *src, size_t n); +extern uint16_t * + u16_move (uint16_t *dest, const uint16_t *src, size_t n); +extern uint32_t * + u32_move (uint32_t *dest, const uint32_t *src, size_t n); + +/* Set the first N characters of S to UC. UC should be a character that + occupies only 1 unit. */ +/* Similar to memset(). */ +extern uint8_t * + u8_set (uint8_t *s, ucs4_t uc, size_t n); +extern uint16_t * + u16_set (uint16_t *s, ucs4_t uc, size_t n); +extern uint32_t * + u32_set (uint32_t *s, ucs4_t uc, size_t n); + +/* Compare S1 and S2, each of length N. */ +/* Similar to memcmp(). */ +extern int + u8_cmp (const uint8_t *s1, const uint8_t *s2, size_t n); +extern int + u16_cmp (const uint16_t *s1, const uint16_t *s2, size_t n); +extern int + u32_cmp (const uint32_t *s1, const uint32_t *s2, size_t n); + +/* Compare S1 and S2. */ +/* Similar to the gnulib function memcmp2(). */ +extern int + u8_cmp2 (const uint8_t *s1, size_t n1, const uint8_t *s2, size_t n2); +extern int + u16_cmp2 (const uint16_t *s1, size_t n1, const uint16_t *s2, size_t n2); +extern int + u32_cmp2 (const uint32_t *s1, size_t n1, const uint32_t *s2, size_t n2); + +/* Search the string at S for UC. */ +/* Similar to memchr(). */ +extern uint8_t * + u8_chr (const uint8_t *s, size_t n, ucs4_t uc); +extern uint16_t * + u16_chr (const uint16_t *s, size_t n, ucs4_t uc); +extern uint32_t * + u32_chr (const uint32_t *s, size_t n, ucs4_t uc); + +/* Count the number of Unicode characters in the N units from S. */ +/* Similar to mbsnlen(). */ +extern size_t + u8_mbsnlen (const uint8_t *s, size_t n); +extern size_t + u16_mbsnlen (const uint16_t *s, size_t n); +extern size_t + u32_mbsnlen (const uint32_t *s, size_t n); + +/* Elementary string functions with memory allocation. */ + +/* Make a freshly allocated copy of S, of length N. */ +extern uint8_t * + u8_cpy_alloc (const uint8_t *s, size_t n); +extern uint16_t * + u16_cpy_alloc (const uint16_t *s, size_t n); +extern uint32_t * + u32_cpy_alloc (const uint32_t *s, size_t n); + +/* Elementary string functions on NUL terminated strings. */ + +/* Return the length (number of units) of the first character in S. + Return 0 if it is the NUL character. Return -1 upon failure. */ +extern int + u8_strmblen (const uint8_t *s); +extern int + u16_strmblen (const uint16_t *s); +extern int + u32_strmblen (const uint32_t *s); + +/* Return the length (number of units) of the first character in S, putting + its 'ucs4_t' representation in *PUC. Return 0 if it is the NUL + character. Return -1 upon failure. */ +extern int + u8_strmbtouc (ucs4_t *puc, const uint8_t *s); +extern int + u16_strmbtouc (ucs4_t *puc, const uint16_t *s); +extern int + u32_strmbtouc (ucs4_t *puc, const uint32_t *s); + +/* Forward iteration step. Advances the pointer past the next character, + or returns NULL if the end of the string has been reached. Puts the + character's 'ucs4_t' representation in *PUC. */ +extern const uint8_t * + u8_next (ucs4_t *puc, const uint8_t *s); +extern const uint16_t * + u16_next (ucs4_t *puc, const uint16_t *s); +extern const uint32_t * + u32_next (ucs4_t *puc, const uint32_t *s); + +/* Backward iteration step. Advances the pointer to point to the previous + character, or returns NULL if the beginning of the string had been reached. + Puts the character's 'ucs4_t' representation in *PUC. */ +extern const uint8_t * + u8_prev (ucs4_t *puc, const uint8_t *s, const uint8_t *start); +extern const uint16_t * + u16_prev (ucs4_t *puc, const uint16_t *s, const uint16_t *start); +extern const uint32_t * + u32_prev (ucs4_t *puc, const uint32_t *s, const uint32_t *start); + +/* Return the number of units in S. */ +/* Similar to strlen(), wcslen(). */ +extern size_t + u8_strlen (const uint8_t *s); +extern size_t + u16_strlen (const uint16_t *s); +extern size_t + u32_strlen (const uint32_t *s); + +/* Return the number of units in S, but at most MAXLEN. */ +/* Similar to strnlen(), wcsnlen(). */ +extern size_t + u8_strnlen (const uint8_t *s, size_t maxlen); +extern size_t + u16_strnlen (const uint16_t *s, size_t maxlen); +extern size_t + u32_strnlen (const uint32_t *s, size_t maxlen); + +/* Copy SRC to DEST. */ +/* Similar to strcpy(), wcscpy(). */ +extern uint8_t * + u8_strcpy (uint8_t *dest, const uint8_t *src); +extern uint16_t * + u16_strcpy (uint16_t *dest, const uint16_t *src); +extern uint32_t * + u32_strcpy (uint32_t *dest, const uint32_t *src); + +/* Copy SRC to DEST, returning the address of the terminating NUL in DEST. */ +/* Similar to stpcpy(). */ +extern uint8_t * + u8_stpcpy (uint8_t *dest, const uint8_t *src); +extern uint16_t * + u16_stpcpy (uint16_t *dest, const uint16_t *src); +extern uint32_t * + u32_stpcpy (uint32_t *dest, const uint32_t *src); + +/* Copy no more than N units of SRC to DEST. */ +/* Similar to strncpy(), wcsncpy(). */ +extern uint8_t * + u8_strncpy (uint8_t *dest, const uint8_t *src, size_t n); +extern uint16_t * + u16_strncpy (uint16_t *dest, const uint16_t *src, size_t n); +extern uint32_t * + u32_strncpy (uint32_t *dest, const uint32_t *src, size_t n); + +/* Copy no more than N units of SRC to DEST, returning the address of + the last unit written into DEST. */ +/* Similar to stpncpy(). */ +extern uint8_t * + u8_stpncpy (uint8_t *dest, const uint8_t *src, size_t n); +extern uint16_t * + u16_stpncpy (uint16_t *dest, const uint16_t *src, size_t n); +extern uint32_t * + u32_stpncpy (uint32_t *dest, const uint32_t *src, size_t n); + +/* Append SRC onto DEST. */ +/* Similar to strcat(), wcscat(). */ +extern uint8_t * + u8_strcat (uint8_t *dest, const uint8_t *src); +extern uint16_t * + u16_strcat (uint16_t *dest, const uint16_t *src); +extern uint32_t * + u32_strcat (uint32_t *dest, const uint32_t *src); + +/* Append no more than N units of SRC onto DEST. */ +/* Similar to strncat(), wcsncat(). */ +extern uint8_t * + u8_strncat (uint8_t *dest, const uint8_t *src, size_t n); +extern uint16_t * + u16_strncat (uint16_t *dest, const uint16_t *src, size_t n); +extern uint32_t * + u32_strncat (uint32_t *dest, const uint32_t *src, size_t n); + +/* Compare S1 and S2. */ +/* Similar to strcmp(), wcscmp(). */ +extern int + u8_strcmp (const uint8_t *s1, const uint8_t *s2); +extern int + u16_strcmp (const uint16_t *s1, const uint16_t *s2); +extern int + u32_strcmp (const uint32_t *s1, const uint32_t *s2); + +/* Compare S1 and S2 using the collation rules of the current locale. + Return -1 if S1 < S2, 0 if S1 = S2, 1 if S1 > S2. + Upon failure, set errno and return any value. */ +/* Similar to strcoll(), wcscoll(). */ +extern int + u8_strcoll (const uint8_t *s1, const uint8_t *s2); +extern int + u16_strcoll (const uint16_t *s1, const uint16_t *s2); +extern int + u32_strcoll (const uint32_t *s1, const uint32_t *s2); + +/* Compare no more than N units of S1 and S2. */ +/* Similar to strncmp(), wcsncmp(). */ +extern int + u8_strncmp (const uint8_t *s1, const uint8_t *s2, size_t n); +extern int + u16_strncmp (const uint16_t *s1, const uint16_t *s2, size_t n); +extern int + u32_strncmp (const uint32_t *s1, const uint32_t *s2, size_t n); + +/* Duplicate S, returning an identical malloc'd string. */ +/* Similar to strdup(), wcsdup(). */ +extern uint8_t * + u8_strdup (const uint8_t *s); +extern uint16_t * + u16_strdup (const uint16_t *s); +extern uint32_t * + u32_strdup (const uint32_t *s); + +/* Find the first occurrence of UC in STR. */ +/* Similar to strchr(), wcschr(). */ +extern uint8_t * + u8_strchr (const uint8_t *str, ucs4_t uc); +extern uint16_t * + u16_strchr (const uint16_t *str, ucs4_t uc); +extern uint32_t * + u32_strchr (const uint32_t *str, ucs4_t uc); + +/* Find the last occurrence of UC in STR. */ +/* Similar to strrchr(), wcsrchr(). */ +extern uint8_t * + u8_strrchr (const uint8_t *str, ucs4_t uc); +extern uint16_t * + u16_strrchr (const uint16_t *str, ucs4_t uc); +extern uint32_t * + u32_strrchr (const uint32_t *str, ucs4_t uc); + +/* Return the length of the initial segment of STR which consists entirely + of Unicode characters not in REJECT. */ +/* Similar to strcspn(), wcscspn(). */ +extern size_t + u8_strcspn (const uint8_t *str, const uint8_t *reject); +extern size_t + u16_strcspn (const uint16_t *str, const uint16_t *reject); +extern size_t + u32_strcspn (const uint32_t *str, const uint32_t *reject); + +/* Return the length of the initial segment of STR which consists entirely + of Unicode characters in ACCEPT. */ +/* Similar to strspn(), wcsspn(). */ +extern size_t + u8_strspn (const uint8_t *str, const uint8_t *accept); +extern size_t + u16_strspn (const uint16_t *str, const uint16_t *accept); +extern size_t + u32_strspn (const uint32_t *str, const uint32_t *accept); + +/* Find the first occurrence in STR of any character in ACCEPT. */ +/* Similar to strpbrk(), wcspbrk(). */ +extern uint8_t * + u8_strpbrk (const uint8_t *str, const uint8_t *accept); +extern uint16_t * + u16_strpbrk (const uint16_t *str, const uint16_t *accept); +extern uint32_t * + u32_strpbrk (const uint32_t *str, const uint32_t *accept); + +/* Find the first occurrence of NEEDLE in HAYSTACK. */ +/* Similar to strstr(), wcsstr(). */ +extern uint8_t * + u8_strstr (const uint8_t *haystack, const uint8_t *needle); +extern uint16_t * + u16_strstr (const uint16_t *haystack, const uint16_t *needle); +extern uint32_t * + u32_strstr (const uint32_t *haystack, const uint32_t *needle); + +/* Test whether STR starts with PREFIX. */ +extern bool + u8_startswith (const uint8_t *str, const uint8_t *prefix); +extern bool + u16_startswith (const uint16_t *str, const uint16_t *prefix); +extern bool + u32_startswith (const uint32_t *str, const uint32_t *prefix); + +/* Test whether STR ends with SUFFIX. */ +extern bool + u8_endswith (const uint8_t *str, const uint8_t *suffix); +extern bool + u16_endswith (const uint16_t *str, const uint16_t *suffix); +extern bool + u32_endswith (const uint32_t *str, const uint32_t *suffix); + +/* Divide STR into tokens separated by characters in DELIM. + This interface is actually more similar to wcstok than to strtok. */ +/* Similar to strtok_r(), wcstok(). */ +extern uint8_t * + u8_strtok (uint8_t *str, const uint8_t *delim, uint8_t **ptr); +extern uint16_t * + u16_strtok (uint16_t *str, const uint16_t *delim, uint16_t **ptr); +extern uint32_t * + u32_strtok (uint32_t *str, const uint32_t *delim, uint32_t **ptr); + + +#ifdef __cplusplus +} +#endif + +#endif /* _UNISTR_H */ diff --git a/lib/unistr/u8-mbtouc-aux.c b/lib/unistr/u8-mbtouc-aux.c new file mode 100644 index 000000000..53d02bf0d --- /dev/null +++ b/lib/unistr/u8-mbtouc-aux.c @@ -0,0 +1,158 @@ +/* Conversion UTF-8 to UCS-4. + Copyright (C) 2001-2002, 2006-2007, 2009 Free Software Foundation, Inc. + Written by Bruno Haible , 2001. + + This program is free software: you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#include + +/* Specification. */ +#include "unistr.h" + +#if defined IN_LIBUNISTRING || HAVE_INLINE + +int +u8_mbtouc_aux (ucs4_t *puc, const uint8_t *s, size_t n) +{ + uint8_t c = *s; + + if (c >= 0xc2) + { + if (c < 0xe0) + { + if (n >= 2) + { + if ((s[1] ^ 0x80) < 0x40) + { + *puc = ((unsigned int) (c & 0x1f) << 6) + | (unsigned int) (s[1] ^ 0x80); + return 2; + } + /* invalid multibyte character */ + } + else + { + /* incomplete multibyte character */ + *puc = 0xfffd; + return n; + } + } + else if (c < 0xf0) + { + if (n >= 3) + { + if ((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40 + && (c >= 0xe1 || s[1] >= 0xa0) + && (c != 0xed || s[1] < 0xa0)) + { + *puc = ((unsigned int) (c & 0x0f) << 12) + | ((unsigned int) (s[1] ^ 0x80) << 6) + | (unsigned int) (s[2] ^ 0x80); + return 3; + } + /* invalid multibyte character */ + } + else + { + /* incomplete multibyte character */ + *puc = 0xfffd; + return n; + } + } + else if (c < 0xf8) + { + if (n >= 4) + { + if ((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40 + && (s[3] ^ 0x80) < 0x40 + && (c >= 0xf1 || s[1] >= 0x90) +#if 1 + && (c < 0xf4 || (c == 0xf4 && s[1] < 0x90)) +#endif + ) + { + *puc = ((unsigned int) (c & 0x07) << 18) + | ((unsigned int) (s[1] ^ 0x80) << 12) + | ((unsigned int) (s[2] ^ 0x80) << 6) + | (unsigned int) (s[3] ^ 0x80); + return 4; + } + /* invalid multibyte character */ + } + else + { + /* incomplete multibyte character */ + *puc = 0xfffd; + return n; + } + } +#if 0 + else if (c < 0xfc) + { + if (n >= 5) + { + if ((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40 + && (s[3] ^ 0x80) < 0x40 && (s[4] ^ 0x80) < 0x40 + && (c >= 0xf9 || s[1] >= 0x88)) + { + *puc = ((unsigned int) (c & 0x03) << 24) + | ((unsigned int) (s[1] ^ 0x80) << 18) + | ((unsigned int) (s[2] ^ 0x80) << 12) + | ((unsigned int) (s[3] ^ 0x80) << 6) + | (unsigned int) (s[4] ^ 0x80); + return 5; + } + /* invalid multibyte character */ + } + else + { + /* incomplete multibyte character */ + *puc = 0xfffd; + return n; + } + } + else if (c < 0xfe) + { + if (n >= 6) + { + if ((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40 + && (s[3] ^ 0x80) < 0x40 && (s[4] ^ 0x80) < 0x40 + && (s[5] ^ 0x80) < 0x40 + && (c >= 0xfd || s[1] >= 0x84)) + { + *puc = ((unsigned int) (c & 0x01) << 30) + | ((unsigned int) (s[1] ^ 0x80) << 24) + | ((unsigned int) (s[2] ^ 0x80) << 18) + | ((unsigned int) (s[3] ^ 0x80) << 12) + | ((unsigned int) (s[4] ^ 0x80) << 6) + | (unsigned int) (s[5] ^ 0x80); + return 6; + } + /* invalid multibyte character */ + } + else + { + /* incomplete multibyte character */ + *puc = 0xfffd; + return n; + } + } +#endif + } + /* invalid multibyte character */ + *puc = 0xfffd; + return 1; +} + +#endif diff --git a/lib/unistr/u8-mbtouc-unsafe-aux.c b/lib/unistr/u8-mbtouc-unsafe-aux.c new file mode 100644 index 000000000..43e4a360f --- /dev/null +++ b/lib/unistr/u8-mbtouc-unsafe-aux.c @@ -0,0 +1,168 @@ +/* Conversion UTF-8 to UCS-4. + Copyright (C) 2001-2002, 2006-2007, 2009 Free Software Foundation, Inc. + Written by Bruno Haible , 2001. + + This program is free software: you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#include + +/* Specification. */ +#include "unistr.h" + +#if defined IN_LIBUNISTRING || HAVE_INLINE + +int +u8_mbtouc_unsafe_aux (ucs4_t *puc, const uint8_t *s, size_t n) +{ + uint8_t c = *s; + + if (c >= 0xc2) + { + if (c < 0xe0) + { + if (n >= 2) + { +#if CONFIG_UNICODE_SAFETY + if ((s[1] ^ 0x80) < 0x40) +#endif + { + *puc = ((unsigned int) (c & 0x1f) << 6) + | (unsigned int) (s[1] ^ 0x80); + return 2; + } + /* invalid multibyte character */ + } + else + { + /* incomplete multibyte character */ + *puc = 0xfffd; + return n; + } + } + else if (c < 0xf0) + { + if (n >= 3) + { +#if CONFIG_UNICODE_SAFETY + if ((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40 + && (c >= 0xe1 || s[1] >= 0xa0) + && (c != 0xed || s[1] < 0xa0)) +#endif + { + *puc = ((unsigned int) (c & 0x0f) << 12) + | ((unsigned int) (s[1] ^ 0x80) << 6) + | (unsigned int) (s[2] ^ 0x80); + return 3; + } + /* invalid multibyte character */ + } + else + { + /* incomplete multibyte character */ + *puc = 0xfffd; + return n; + } + } + else if (c < 0xf8) + { + if (n >= 4) + { +#if CONFIG_UNICODE_SAFETY + if ((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40 + && (s[3] ^ 0x80) < 0x40 + && (c >= 0xf1 || s[1] >= 0x90) +#if 1 + && (c < 0xf4 || (c == 0xf4 && s[1] < 0x90)) +#endif + ) +#endif + { + *puc = ((unsigned int) (c & 0x07) << 18) + | ((unsigned int) (s[1] ^ 0x80) << 12) + | ((unsigned int) (s[2] ^ 0x80) << 6) + | (unsigned int) (s[3] ^ 0x80); + return 4; + } + /* invalid multibyte character */ + } + else + { + /* incomplete multibyte character */ + *puc = 0xfffd; + return n; + } + } +#if 0 + else if (c < 0xfc) + { + if (n >= 5) + { +#if CONFIG_UNICODE_SAFETY + if ((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40 + && (s[3] ^ 0x80) < 0x40 && (s[4] ^ 0x80) < 0x40 + && (c >= 0xf9 || s[1] >= 0x88)) +#endif + { + *puc = ((unsigned int) (c & 0x03) << 24) + | ((unsigned int) (s[1] ^ 0x80) << 18) + | ((unsigned int) (s[2] ^ 0x80) << 12) + | ((unsigned int) (s[3] ^ 0x80) << 6) + | (unsigned int) (s[4] ^ 0x80); + return 5; + } + /* invalid multibyte character */ + } + else + { + /* incomplete multibyte character */ + *puc = 0xfffd; + return n; + } + } + else if (c < 0xfe) + { + if (n >= 6) + { +#if CONFIG_UNICODE_SAFETY + if ((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40 + && (s[3] ^ 0x80) < 0x40 && (s[4] ^ 0x80) < 0x40 + && (s[5] ^ 0x80) < 0x40 + && (c >= 0xfd || s[1] >= 0x84)) +#endif + { + *puc = ((unsigned int) (c & 0x01) << 30) + | ((unsigned int) (s[1] ^ 0x80) << 24) + | ((unsigned int) (s[2] ^ 0x80) << 18) + | ((unsigned int) (s[3] ^ 0x80) << 12) + | ((unsigned int) (s[4] ^ 0x80) << 6) + | (unsigned int) (s[5] ^ 0x80); + return 6; + } + /* invalid multibyte character */ + } + else + { + /* incomplete multibyte character */ + *puc = 0xfffd; + return n; + } + } +#endif + } + /* invalid multibyte character */ + *puc = 0xfffd; + return 1; +} + +#endif diff --git a/lib/unistr/u8-mbtouc-unsafe.c b/lib/unistr/u8-mbtouc-unsafe.c new file mode 100644 index 000000000..466156967 --- /dev/null +++ b/lib/unistr/u8-mbtouc-unsafe.c @@ -0,0 +1,179 @@ +/* Look at first character in UTF-8 string. + Copyright (C) 1999-2002, 2006-2007, 2009 Free Software Foundation, Inc. + Written by Bruno Haible , 2001. + + This program is free software: you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#include + +#if defined IN_LIBUNISTRING +/* Tell unistr.h to declare u8_mbtouc_unsafe as 'extern', not + 'static inline'. */ +# include "unistring-notinline.h" +#endif + +/* Specification. */ +#include "unistr.h" + +#if !HAVE_INLINE + +int +u8_mbtouc_unsafe (ucs4_t *puc, const uint8_t *s, size_t n) +{ + uint8_t c = *s; + + if (c < 0x80) + { + *puc = c; + return 1; + } + else if (c >= 0xc2) + { + if (c < 0xe0) + { + if (n >= 2) + { +#if CONFIG_UNICODE_SAFETY + if ((s[1] ^ 0x80) < 0x40) +#endif + { + *puc = ((unsigned int) (c & 0x1f) << 6) + | (unsigned int) (s[1] ^ 0x80); + return 2; + } + /* invalid multibyte character */ + } + else + { + /* incomplete multibyte character */ + *puc = 0xfffd; + return n; + } + } + else if (c < 0xf0) + { + if (n >= 3) + { +#if CONFIG_UNICODE_SAFETY + if ((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40 + && (c >= 0xe1 || s[1] >= 0xa0) + && (c != 0xed || s[1] < 0xa0)) +#endif + { + *puc = ((unsigned int) (c & 0x0f) << 12) + | ((unsigned int) (s[1] ^ 0x80) << 6) + | (unsigned int) (s[2] ^ 0x80); + return 3; + } + /* invalid multibyte character */ + } + else + { + /* incomplete multibyte character */ + *puc = 0xfffd; + return n; + } + } + else if (c < 0xf8) + { + if (n >= 4) + { +#if CONFIG_UNICODE_SAFETY + if ((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40 + && (s[3] ^ 0x80) < 0x40 + && (c >= 0xf1 || s[1] >= 0x90) +#if 1 + && (c < 0xf4 || (c == 0xf4 && s[1] < 0x90)) +#endif + ) +#endif + { + *puc = ((unsigned int) (c & 0x07) << 18) + | ((unsigned int) (s[1] ^ 0x80) << 12) + | ((unsigned int) (s[2] ^ 0x80) << 6) + | (unsigned int) (s[3] ^ 0x80); + return 4; + } + /* invalid multibyte character */ + } + else + { + /* incomplete multibyte character */ + *puc = 0xfffd; + return n; + } + } +#if 0 + else if (c < 0xfc) + { + if (n >= 5) + { +#if CONFIG_UNICODE_SAFETY + if ((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40 + && (s[3] ^ 0x80) < 0x40 && (s[4] ^ 0x80) < 0x40 + && (c >= 0xf9 || s[1] >= 0x88)) +#endif + { + *puc = ((unsigned int) (c & 0x03) << 24) + | ((unsigned int) (s[1] ^ 0x80) << 18) + | ((unsigned int) (s[2] ^ 0x80) << 12) + | ((unsigned int) (s[3] ^ 0x80) << 6) + | (unsigned int) (s[4] ^ 0x80); + return 5; + } + /* invalid multibyte character */ + } + else + { + /* incomplete multibyte character */ + *puc = 0xfffd; + return n; + } + } + else if (c < 0xfe) + { + if (n >= 6) + { +#if CONFIG_UNICODE_SAFETY + if ((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40 + && (s[3] ^ 0x80) < 0x40 && (s[4] ^ 0x80) < 0x40 + && (s[5] ^ 0x80) < 0x40 + && (c >= 0xfd || s[1] >= 0x84)) +#endif + { + *puc = ((unsigned int) (c & 0x01) << 30) + | ((unsigned int) (s[1] ^ 0x80) << 24) + | ((unsigned int) (s[2] ^ 0x80) << 18) + | ((unsigned int) (s[3] ^ 0x80) << 12) + | ((unsigned int) (s[4] ^ 0x80) << 6) + | (unsigned int) (s[5] ^ 0x80); + return 6; + } + /* invalid multibyte character */ + } + else + { + /* incomplete multibyte character */ + *puc = 0xfffd; + return n; + } + } +#endif + } + /* invalid multibyte character */ + *puc = 0xfffd; + return 1; +} + +#endif diff --git a/lib/unistr/u8-mbtouc.c b/lib/unistr/u8-mbtouc.c new file mode 100644 index 000000000..ff624f17d --- /dev/null +++ b/lib/unistr/u8-mbtouc.c @@ -0,0 +1,168 @@ +/* Look at first character in UTF-8 string. + Copyright (C) 1999-2002, 2006-2007, 2009 Free Software Foundation, Inc. + Written by Bruno Haible , 2001. + + This program is free software: you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#include + +#if defined IN_LIBUNISTRING +/* Tell unistr.h to declare u8_mbtouc as 'extern', not 'static inline'. */ +# include "unistring-notinline.h" +#endif + +/* Specification. */ +#include "unistr.h" + +#if !HAVE_INLINE + +int +u8_mbtouc (ucs4_t *puc, const uint8_t *s, size_t n) +{ + uint8_t c = *s; + + if (c < 0x80) + { + *puc = c; + return 1; + } + else if (c >= 0xc2) + { + if (c < 0xe0) + { + if (n >= 2) + { + if ((s[1] ^ 0x80) < 0x40) + { + *puc = ((unsigned int) (c & 0x1f) << 6) + | (unsigned int) (s[1] ^ 0x80); + return 2; + } + /* invalid multibyte character */ + } + else + { + /* incomplete multibyte character */ + *puc = 0xfffd; + return n; + } + } + else if (c < 0xf0) + { + if (n >= 3) + { + if ((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40 + && (c >= 0xe1 || s[1] >= 0xa0) + && (c != 0xed || s[1] < 0xa0)) + { + *puc = ((unsigned int) (c & 0x0f) << 12) + | ((unsigned int) (s[1] ^ 0x80) << 6) + | (unsigned int) (s[2] ^ 0x80); + return 3; + } + /* invalid multibyte character */ + } + else + { + /* incomplete multibyte character */ + *puc = 0xfffd; + return n; + } + } + else if (c < 0xf8) + { + if (n >= 4) + { + if ((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40 + && (s[3] ^ 0x80) < 0x40 + && (c >= 0xf1 || s[1] >= 0x90) +#if 1 + && (c < 0xf4 || (c == 0xf4 && s[1] < 0x90)) +#endif + ) + { + *puc = ((unsigned int) (c & 0x07) << 18) + | ((unsigned int) (s[1] ^ 0x80) << 12) + | ((unsigned int) (s[2] ^ 0x80) << 6) + | (unsigned int) (s[3] ^ 0x80); + return 4; + } + /* invalid multibyte character */ + } + else + { + /* incomplete multibyte character */ + *puc = 0xfffd; + return n; + } + } +#if 0 + else if (c < 0xfc) + { + if (n >= 5) + { + if ((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40 + && (s[3] ^ 0x80) < 0x40 && (s[4] ^ 0x80) < 0x40 + && (c >= 0xf9 || s[1] >= 0x88)) + { + *puc = ((unsigned int) (c & 0x03) << 24) + | ((unsigned int) (s[1] ^ 0x80) << 18) + | ((unsigned int) (s[2] ^ 0x80) << 12) + | ((unsigned int) (s[3] ^ 0x80) << 6) + | (unsigned int) (s[4] ^ 0x80); + return 5; + } + /* invalid multibyte character */ + } + else + { + /* incomplete multibyte character */ + *puc = 0xfffd; + return n; + } + } + else if (c < 0xfe) + { + if (n >= 6) + { + if ((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40 + && (s[3] ^ 0x80) < 0x40 && (s[4] ^ 0x80) < 0x40 + && (s[5] ^ 0x80) < 0x40 + && (c >= 0xfd || s[1] >= 0x84)) + { + *puc = ((unsigned int) (c & 0x01) << 30) + | ((unsigned int) (s[1] ^ 0x80) << 24) + | ((unsigned int) (s[2] ^ 0x80) << 18) + | ((unsigned int) (s[3] ^ 0x80) << 12) + | ((unsigned int) (s[4] ^ 0x80) << 6) + | (unsigned int) (s[5] ^ 0x80); + return 6; + } + /* invalid multibyte character */ + } + else + { + /* incomplete multibyte character */ + *puc = 0xfffd; + return n; + } + } +#endif + } + /* invalid multibyte character */ + *puc = 0xfffd; + return 1; +} + +#endif diff --git a/lib/unistr/u8-mbtoucr.c b/lib/unistr/u8-mbtoucr.c new file mode 100644 index 000000000..dd8335247 --- /dev/null +++ b/lib/unistr/u8-mbtoucr.c @@ -0,0 +1,285 @@ +/* Look at first character in UTF-8 string, returning an error code. + Copyright (C) 1999-2002, 2006-2007 Free Software Foundation, Inc. + Written by Bruno Haible , 2001. + + This program is free software: you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#include + +/* Specification. */ +#include "unistr.h" + +int +u8_mbtoucr (ucs4_t *puc, const uint8_t *s, size_t n) +{ + uint8_t c = *s; + + if (c < 0x80) + { + *puc = c; + return 1; + } + else if (c >= 0xc2) + { + if (c < 0xe0) + { + if (n >= 2) + { + if ((s[1] ^ 0x80) < 0x40) + { + *puc = ((unsigned int) (c & 0x1f) << 6) + | (unsigned int) (s[1] ^ 0x80); + return 2; + } + /* invalid multibyte character */ + } + else + { + /* incomplete multibyte character */ + *puc = 0xfffd; + return -2; + } + } + else if (c < 0xf0) + { + if (n >= 2) + { + if ((s[1] ^ 0x80) < 0x40 + && (c >= 0xe1 || s[1] >= 0xa0) + && (c != 0xed || s[1] < 0xa0)) + { + if (n >= 3) + { + if ((s[2] ^ 0x80) < 0x40) + { + *puc = ((unsigned int) (c & 0x0f) << 12) + | ((unsigned int) (s[1] ^ 0x80) << 6) + | (unsigned int) (s[2] ^ 0x80); + return 3; + } + /* invalid multibyte character */ + } + else + { + /* incomplete multibyte character */ + *puc = 0xfffd; + return -2; + } + } + /* invalid multibyte character */ + } + else + { + /* incomplete multibyte character */ + *puc = 0xfffd; + return -2; + } + } + else if (c < 0xf8) + { + if (n >= 2) + { + if ((s[1] ^ 0x80) < 0x40 + && (c >= 0xf1 || s[1] >= 0x90) +#if 1 + && (c < 0xf4 || (c == 0xf4 && s[1] < 0x90)) +#endif + ) + { + if (n >= 3) + { + if ((s[2] ^ 0x80) < 0x40) + { + if (n >= 4) + { + if ((s[3] ^ 0x80) < 0x40) + { + *puc = ((unsigned int) (c & 0x07) << 18) + | ((unsigned int) (s[1] ^ 0x80) << 12) + | ((unsigned int) (s[2] ^ 0x80) << 6) + | (unsigned int) (s[3] ^ 0x80); + return 4; + } + /* invalid multibyte character */ + } + else + { + /* incomplete multibyte character */ + *puc = 0xfffd; + return -2; + } + } + /* invalid multibyte character */ + } + else + { + /* incomplete multibyte character */ + *puc = 0xfffd; + return -2; + } + } + /* invalid multibyte character */ + } + else + { + /* incomplete multibyte character */ + *puc = 0xfffd; + return -2; + } + } +#if 0 + else if (c < 0xfc) + { + if (n >= 2) + { + if ((s[1] ^ 0x80) < 0x40 + && (c >= 0xf9 || s[1] >= 0x88)) + { + if (n >= 3) + { + if ((s[2] ^ 0x80) < 0x40) + { + if (n >= 4) + { + if ((s[3] ^ 0x80) < 0x40) + { + if (n >= 5) + { + if ((s[4] ^ 0x80) < 0x40) + { + *puc = ((unsigned int) (c & 0x03) << 24) + | ((unsigned int) (s[1] ^ 0x80) << 18) + | ((unsigned int) (s[2] ^ 0x80) << 12) + | ((unsigned int) (s[3] ^ 0x80) << 6) + | (unsigned int) (s[4] ^ 0x80); + return 5; + } + /* invalid multibyte character */ + } + else + { + /* incomplete multibyte character */ + *puc = 0xfffd; + return -2; + } + } + /* invalid multibyte character */ + } + else + { + /* incomplete multibyte character */ + *puc = 0xfffd; + return -2; + } + } + /* invalid multibyte character */ + } + else + { + /* incomplete multibyte character */ + *puc = 0xfffd; + return -2; + } + } + /* invalid multibyte character */ + } + else + { + /* incomplete multibyte character */ + *puc = 0xfffd; + return -2; + } + } + else if (c < 0xfe) + { + if (n >= 2) + { + if ((s[1] ^ 0x80) < 0x40 + && (c >= 0xfd || s[1] >= 0x84)) + { + if (n >= 3) + { + if ((s[2] ^ 0x80) < 0x40) + { + if (n >= 4) + { + if ((s[3] ^ 0x80) < 0x40) + { + if (n >= 5) + { + if ((s[4] ^ 0x80) < 0x40) + { + if (n >= 6) + { + if ((s[5] ^ 0x80) < 0x40) + { + *puc = ((unsigned int) (c & 0x01) << 30) + | ((unsigned int) (s[1] ^ 0x80) << 24) + | ((unsigned int) (s[2] ^ 0x80) << 18) + | ((unsigned int) (s[3] ^ 0x80) << 12) + | ((unsigned int) (s[4] ^ 0x80) << 6) + | (unsigned int) (s[5] ^ 0x80); + return 6; + } + /* invalid multibyte character */ + } + else + { + /* incomplete multibyte character */ + *puc = 0xfffd; + return -2; + } + } + /* invalid multibyte character */ + } + else + { + /* incomplete multibyte character */ + *puc = 0xfffd; + return -2; + } + } + /* invalid multibyte character */ + } + else + { + /* incomplete multibyte character */ + *puc = 0xfffd; + return -2; + } + } + /* invalid multibyte character */ + } + else + { + /* incomplete multibyte character */ + *puc = 0xfffd; + return -2; + } + } + /* invalid multibyte character */ + } + else + { + /* incomplete multibyte character */ + *puc = 0xfffd; + return -2; + } + } +#endif + } + /* invalid multibyte character */ + *puc = 0xfffd; + return -1; +} diff --git a/lib/unistr/u8-prev.c b/lib/unistr/u8-prev.c new file mode 100644 index 000000000..245d22ff0 --- /dev/null +++ b/lib/unistr/u8-prev.c @@ -0,0 +1,93 @@ +/* Iterate over previous character in UTF-8 string. + Copyright (C) 2002, 2006-2007 Free Software Foundation, Inc. + Written by Bruno Haible , 2002. + + This program is free software: you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#include + +/* Specification. */ +#include "unistr.h" + +const uint8_t * +u8_prev (ucs4_t *puc, const uint8_t *s, const uint8_t *start) +{ + /* Keep in sync with unistr.h and utf8-ucs4.c. */ + if (s != start) + { + uint8_t c_1 = s[-1]; + + if (c_1 < 0x80) + { + *puc = c_1; + return s - 1; + } +#if CONFIG_UNICODE_SAFETY + if ((c_1 ^ 0x80) < 0x40) +#endif + if (s - 1 != start) + { + uint8_t c_2 = s[-2]; + + if (c_2 >= 0xc2 && c_2 < 0xe0) + { + *puc = ((unsigned int) (c_2 & 0x1f) << 6) + | (unsigned int) (c_1 ^ 0x80); + return s - 2; + } +#if CONFIG_UNICODE_SAFETY + if ((c_2 ^ 0x80) < 0x40) +#endif + if (s - 2 != start) + { + uint8_t c_3 = s[-3]; + + if (c_3 >= 0xe0 && c_3 < 0xf0 +#if CONFIG_UNICODE_SAFETY + && (c_3 >= 0xe1 || c_2 >= 0xa0) + && (c_3 != 0xed || c_2 < 0xa0) +#endif + ) + { + *puc = ((unsigned int) (c_3 & 0x0f) << 12) + | ((unsigned int) (c_2 ^ 0x80) << 6) + | (unsigned int) (c_1 ^ 0x80); + return s - 3; + } +#if CONFIG_UNICODE_SAFETY + if ((c_3 ^ 0x80) < 0x40) +#endif + if (s - 3 != start) + { + uint8_t c_4 = s[-4]; + + if (c_4 >= 0xf0 && c_4 < 0xf8 +#if CONFIG_UNICODE_SAFETY + && (c_4 >= 0xf1 || c_3 >= 0x90) + && (c_4 < 0xf4 || (c_4 == 0xf4 && c_3 < 0x90)) +#endif + ) + { + *puc = ((unsigned int) (c_4 & 0x07) << 18) + | ((unsigned int) (c_3 ^ 0x80) << 12) + | ((unsigned int) (c_2 ^ 0x80) << 6) + | (unsigned int) (c_1 ^ 0x80); + return s - 4; + } + } + } + } + } + return NULL; +} diff --git a/lib/unistr/u8-uctomb-aux.c b/lib/unistr/u8-uctomb-aux.c new file mode 100644 index 000000000..c42fa5015 --- /dev/null +++ b/lib/unistr/u8-uctomb-aux.c @@ -0,0 +1,69 @@ +/* Conversion UCS-4 to UTF-8. + Copyright (C) 2002, 2006-2007 Free Software Foundation, Inc. + Written by Bruno Haible , 2002. + + This program is free software: you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#include + +/* Specification. */ +#include "unistr.h" + +int +u8_uctomb_aux (uint8_t *s, ucs4_t uc, int n) +{ + int count; + + if (uc < 0x80) + /* The case n >= 1 is already handled by the caller. */ + return -2; + else if (uc < 0x800) + count = 2; + else if (uc < 0x10000) + { + if (uc < 0xd800 || uc >= 0xe000) + count = 3; + else + return -1; + } +#if 0 + else if (uc < 0x200000) + count = 4; + else if (uc < 0x4000000) + count = 5; + else if (uc <= 0x7fffffff) + count = 6; +#else + else if (uc < 0x110000) + count = 4; +#endif + else + return -1; + + if (n < count) + return -2; + + switch (count) /* note: code falls through cases! */ + { +#if 0 + case 6: s[5] = 0x80 | (uc & 0x3f); uc = uc >> 6; uc |= 0x4000000; + case 5: s[4] = 0x80 | (uc & 0x3f); uc = uc >> 6; uc |= 0x200000; +#endif + case 4: s[3] = 0x80 | (uc & 0x3f); uc = uc >> 6; uc |= 0x10000; + case 3: s[2] = 0x80 | (uc & 0x3f); uc = uc >> 6; uc |= 0x800; + case 2: s[1] = 0x80 | (uc & 0x3f); uc = uc >> 6; uc |= 0xc0; + /*case 1:*/ s[0] = uc; + } + return count; +} diff --git a/lib/unistr/u8-uctomb.c b/lib/unistr/u8-uctomb.c new file mode 100644 index 000000000..33921669e --- /dev/null +++ b/lib/unistr/u8-uctomb.c @@ -0,0 +1,88 @@ +/* Store a character in UTF-8 string. + Copyright (C) 2002, 2005-2006, 2009 Free Software Foundation, Inc. + Written by Bruno Haible , 2002. + + This program is free software: you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#include + +#if defined IN_LIBUNISTRING +/* Tell unistr.h to declare u8_uctomb as 'extern', not 'static inline'. */ +# include "unistring-notinline.h" +#endif + +/* Specification. */ +#include "unistr.h" + +#if !HAVE_INLINE + +int +u8_uctomb (uint8_t *s, ucs4_t uc, int n) +{ + if (uc < 0x80) + { + if (n > 0) + { + s[0] = uc; + return 1; + } + /* else return -2, below. */ + } + else + { + int count; + + if (uc < 0x800) + count = 2; + else if (uc < 0x10000) + { + if (uc < 0xd800 || uc >= 0xe000) + count = 3; + else + return -1; + } +#if 0 + else if (uc < 0x200000) + count = 4; + else if (uc < 0x4000000) + count = 5; + else if (uc <= 0x7fffffff) + count = 6; +#else + else if (uc < 0x110000) + count = 4; +#endif + else + return -1; + + if (n >= count) + { + switch (count) /* note: code falls through cases! */ + { +#if 0 + case 6: s[5] = 0x80 | (uc & 0x3f); uc = uc >> 6; uc |= 0x4000000; + case 5: s[4] = 0x80 | (uc & 0x3f); uc = uc >> 6; uc |= 0x200000; +#endif + case 4: s[3] = 0x80 | (uc & 0x3f); uc = uc >> 6; uc |= 0x10000; + case 3: s[2] = 0x80 | (uc & 0x3f); uc = uc >> 6; uc |= 0x800; + case 2: s[1] = 0x80 | (uc & 0x3f); uc = uc >> 6; uc |= 0xc0; + /*case 1:*/ s[0] = uc; + } + return count; + } + } + return -2; +} + +#endif diff --git a/lib/unitypes.h b/lib/unitypes.h new file mode 100644 index 000000000..fe8d87735 --- /dev/null +++ b/lib/unitypes.h @@ -0,0 +1,26 @@ +/* Elementary types for the GNU UniString library. + Copyright (C) 2002, 2005-2006 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#ifndef _UNITYPES_H +#define _UNITYPES_H + +/* Get uint8_t, uint16_t, uint32_t. */ +#include + +/* Type representing a Unicode character. */ +typedef uint32_t ucs4_t; + +#endif /* _UNITYPES_H */ diff --git a/lib/vasnprintf.c b/lib/vasnprintf.c new file mode 100644 index 000000000..c620b4c06 --- /dev/null +++ b/lib/vasnprintf.c @@ -0,0 +1,5487 @@ +/* vsprintf with automatic memory allocation. + Copyright (C) 1999, 2002-2009 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2, 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License along + with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* This file can be parametrized with the following macros: + VASNPRINTF The name of the function being defined. + FCHAR_T The element type of the format string. + DCHAR_T The element type of the destination (result) string. + FCHAR_T_ONLY_ASCII Set to 1 to enable verification that all characters + in the format string are ASCII. MUST be set if + FCHAR_T and DCHAR_T are not the same type. + DIRECTIVE Structure denoting a format directive. + Depends on FCHAR_T. + DIRECTIVES Structure denoting the set of format directives of a + format string. Depends on FCHAR_T. + PRINTF_PARSE Function that parses a format string. + Depends on FCHAR_T. + DCHAR_CPY memcpy like function for DCHAR_T[] arrays. + DCHAR_SET memset like function for DCHAR_T[] arrays. + DCHAR_MBSNLEN mbsnlen like function for DCHAR_T[] arrays. + SNPRINTF The system's snprintf (or similar) function. + This may be either snprintf or swprintf. + TCHAR_T The element type of the argument and result string + of the said SNPRINTF function. This may be either + char or wchar_t. The code exploits that + sizeof (TCHAR_T) | sizeof (DCHAR_T) and + alignof (TCHAR_T) <= alignof (DCHAR_T). + DCHAR_IS_TCHAR Set to 1 if DCHAR_T and TCHAR_T are the same type. + DCHAR_CONV_FROM_ENCODING A function to convert from char[] to DCHAR[]. + DCHAR_IS_UINT8_T Set to 1 if DCHAR_T is uint8_t. + DCHAR_IS_UINT16_T Set to 1 if DCHAR_T is uint16_t. + DCHAR_IS_UINT32_T Set to 1 if DCHAR_T is uint32_t. */ + +/* Tell glibc's to provide a prototype for snprintf(). + This must come before because may include + , and once has been included, it's too late. */ +#ifndef _GNU_SOURCE +# define _GNU_SOURCE 1 +#endif + +#ifndef VASNPRINTF +# include +#endif +#ifndef IN_LIBINTL +# include +#endif + +/* Specification. */ +#ifndef VASNPRINTF +# if WIDE_CHAR_VERSION +# include "vasnwprintf.h" +# else +# include "vasnprintf.h" +# endif +#endif + +#include /* localeconv() */ +#include /* snprintf(), sprintf() */ +#include /* abort(), malloc(), realloc(), free() */ +#include /* memcpy(), strlen() */ +#include /* errno */ +#include /* CHAR_BIT */ +#include /* DBL_MAX_EXP, LDBL_MAX_EXP */ +#if HAVE_NL_LANGINFO +# include +#endif +#ifndef VASNPRINTF +# if WIDE_CHAR_VERSION +# include "wprintf-parse.h" +# else +# include "printf-parse.h" +# endif +#endif + +/* Checked size_t computations. */ +#include "xsize.h" + +#if (NEED_PRINTF_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL +# include +# include "float+.h" +#endif + +#if (NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && !defined IN_LIBINTL +# include +# include "isnand-nolibm.h" +#endif + +#if (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE) && !defined IN_LIBINTL +# include +# include "isnanl-nolibm.h" +# include "fpucw.h" +#endif + +#if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL +# include +# include "isnand-nolibm.h" +# include "printf-frexp.h" +#endif + +#if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL +# include +# include "isnanl-nolibm.h" +# include "printf-frexpl.h" +# include "fpucw.h" +#endif + +/* Default parameters. */ +#ifndef VASNPRINTF +# if WIDE_CHAR_VERSION +# define VASNPRINTF vasnwprintf +# define FCHAR_T wchar_t +# define DCHAR_T wchar_t +# define TCHAR_T wchar_t +# define DCHAR_IS_TCHAR 1 +# define DIRECTIVE wchar_t_directive +# define DIRECTIVES wchar_t_directives +# define PRINTF_PARSE wprintf_parse +# define DCHAR_CPY wmemcpy +# define DCHAR_SET wmemset +# else +# define VASNPRINTF vasnprintf +# define FCHAR_T char +# define DCHAR_T char +# define TCHAR_T char +# define DCHAR_IS_TCHAR 1 +# define DIRECTIVE char_directive +# define DIRECTIVES char_directives +# define PRINTF_PARSE printf_parse +# define DCHAR_CPY memcpy +# define DCHAR_SET memset +# endif +#endif +#if WIDE_CHAR_VERSION + /* TCHAR_T is wchar_t. */ +# define USE_SNPRINTF 1 +# if HAVE_DECL__SNWPRINTF + /* On Windows, the function swprintf() has a different signature than + on Unix; we use the _snwprintf() function instead. */ +# define SNPRINTF _snwprintf +# else + /* Unix. */ +# define SNPRINTF swprintf +# endif +#else + /* TCHAR_T is char. */ + /* Use snprintf if it exists under the name 'snprintf' or '_snprintf'. + But don't use it on BeOS, since BeOS snprintf produces no output if the + size argument is >= 0x3000000. + Also don't use it on Linux libc5, since there snprintf with size = 1 + writes any output without bounds, like sprintf. */ +# if (HAVE_DECL__SNPRINTF || HAVE_SNPRINTF) && !defined __BEOS__ && !(__GNU_LIBRARY__ == 1) +# define USE_SNPRINTF 1 +# else +# define USE_SNPRINTF 0 +# endif +# if HAVE_DECL__SNPRINTF + /* Windows. */ +# define SNPRINTF _snprintf +# else + /* Unix. */ +# define SNPRINTF snprintf + /* Here we need to call the native snprintf, not rpl_snprintf. */ +# undef snprintf +# endif +#endif +/* Here we need to call the native sprintf, not rpl_sprintf. */ +#undef sprintf + +/* GCC >= 4.0 with -Wall emits unjustified "... may be used uninitialized" + warnings in this file. Use -Dlint to suppress them. */ +#ifdef lint +# define IF_LINT(Code) Code +#else +# define IF_LINT(Code) /* empty */ +#endif + +/* Avoid some warnings from "gcc -Wshadow". + This file doesn't use the exp() and remainder() functions. */ +#undef exp +#define exp expo +#undef remainder +#define remainder rem + +#if !USE_SNPRINTF && !WIDE_CHAR_VERSION +# if (HAVE_STRNLEN && !defined _AIX) +# define local_strnlen strnlen +# else +# ifndef local_strnlen_defined +# define local_strnlen_defined 1 +static size_t +local_strnlen (const char *string, size_t maxlen) +{ + const char *end = memchr (string, '\0', maxlen); + return end ? (size_t) (end - string) : maxlen; +} +# endif +# endif +#endif + +#if (!USE_SNPRINTF || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL)) && HAVE_WCHAR_T && (WIDE_CHAR_VERSION || DCHAR_IS_TCHAR) +# if HAVE_WCSLEN +# define local_wcslen wcslen +# else + /* Solaris 2.5.1 has wcslen() in a separate library libw.so. To avoid + a dependency towards this library, here is a local substitute. + Define this substitute only once, even if this file is included + twice in the same compilation unit. */ +# ifndef local_wcslen_defined +# define local_wcslen_defined 1 +static size_t +local_wcslen (const wchar_t *s) +{ + const wchar_t *ptr; + + for (ptr = s; *ptr != (wchar_t) 0; ptr++) + ; + return ptr - s; +} +# endif +# endif +#endif + +#if !USE_SNPRINTF && HAVE_WCHAR_T && WIDE_CHAR_VERSION +# if HAVE_WCSNLEN +# define local_wcsnlen wcsnlen +# else +# ifndef local_wcsnlen_defined +# define local_wcsnlen_defined 1 +static size_t +local_wcsnlen (const wchar_t *s, size_t maxlen) +{ + const wchar_t *ptr; + + for (ptr = s; maxlen > 0 && *ptr != (wchar_t) 0; ptr++, maxlen--) + ; + return ptr - s; +} +# endif +# endif +#endif + +#if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && !defined IN_LIBINTL +/* Determine the decimal-point character according to the current locale. */ +# ifndef decimal_point_char_defined +# define decimal_point_char_defined 1 +static char +decimal_point_char () +{ + const char *point; + /* Determine it in a multithread-safe way. We know nl_langinfo is + multithread-safe on glibc systems, but is not required to be multithread- + safe by POSIX. sprintf(), however, is multithread-safe. localeconv() + is rarely multithread-safe. */ +# if HAVE_NL_LANGINFO && __GLIBC__ + point = nl_langinfo (RADIXCHAR); +# elif 1 + char pointbuf[5]; + sprintf (pointbuf, "%#.0f", 1.0); + point = &pointbuf[1]; +# else + point = localeconv () -> decimal_point; +# endif + /* The decimal point is always a single byte: either '.' or ','. */ + return (point[0] != '\0' ? point[0] : '.'); +} +# endif +#endif + +#if NEED_PRINTF_INFINITE_DOUBLE && !NEED_PRINTF_DOUBLE && !defined IN_LIBINTL + +/* Equivalent to !isfinite(x) || x == 0, but does not require libm. */ +static int +is_infinite_or_zero (double x) +{ + return isnand (x) || x + x == x; +} + +#endif + +#if NEED_PRINTF_INFINITE_LONG_DOUBLE && !NEED_PRINTF_LONG_DOUBLE && !defined IN_LIBINTL + +/* Equivalent to !isfinite(x) || x == 0, but does not require libm. */ +static int +is_infinite_or_zerol (long double x) +{ + return isnanl (x) || x + x == x; +} + +#endif + +#if (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL + +/* Converting 'long double' to decimal without rare rounding bugs requires + real bignums. We use the naming conventions of GNU gmp, but vastly simpler + (and slower) algorithms. */ + +typedef unsigned int mp_limb_t; +# define GMP_LIMB_BITS 32 +typedef int mp_limb_verify[2 * (sizeof (mp_limb_t) * CHAR_BIT == GMP_LIMB_BITS) - 1]; + +typedef unsigned long long mp_twolimb_t; +# define GMP_TWOLIMB_BITS 64 +typedef int mp_twolimb_verify[2 * (sizeof (mp_twolimb_t) * CHAR_BIT == GMP_TWOLIMB_BITS) - 1]; + +/* Representation of a bignum >= 0. */ +typedef struct +{ + size_t nlimbs; + mp_limb_t *limbs; /* Bits in little-endian order, allocated with malloc(). */ +} mpn_t; + +/* Compute the product of two bignums >= 0. + Return the allocated memory in case of success, NULL in case of memory + allocation failure. */ +static void * +multiply (mpn_t src1, mpn_t src2, mpn_t *dest) +{ + const mp_limb_t *p1; + const mp_limb_t *p2; + size_t len1; + size_t len2; + + if (src1.nlimbs <= src2.nlimbs) + { + len1 = src1.nlimbs; + p1 = src1.limbs; + len2 = src2.nlimbs; + p2 = src2.limbs; + } + else + { + len1 = src2.nlimbs; + p1 = src2.limbs; + len2 = src1.nlimbs; + p2 = src1.limbs; + } + /* Now 0 <= len1 <= len2. */ + if (len1 == 0) + { + /* src1 or src2 is zero. */ + dest->nlimbs = 0; + dest->limbs = (mp_limb_t *) malloc (1); + } + else + { + /* Here 1 <= len1 <= len2. */ + size_t dlen; + mp_limb_t *dp; + size_t k, i, j; + + dlen = len1 + len2; + dp = (mp_limb_t *) malloc (dlen * sizeof (mp_limb_t)); + if (dp == NULL) + return NULL; + for (k = len2; k > 0; ) + dp[--k] = 0; + for (i = 0; i < len1; i++) + { + mp_limb_t digit1 = p1[i]; + mp_twolimb_t carry = 0; + for (j = 0; j < len2; j++) + { + mp_limb_t digit2 = p2[j]; + carry += (mp_twolimb_t) digit1 * (mp_twolimb_t) digit2; + carry += dp[i + j]; + dp[i + j] = (mp_limb_t) carry; + carry = carry >> GMP_LIMB_BITS; + } + dp[i + len2] = (mp_limb_t) carry; + } + /* Normalise. */ + while (dlen > 0 && dp[dlen - 1] == 0) + dlen--; + dest->nlimbs = dlen; + dest->limbs = dp; + } + return dest->limbs; +} + +/* Compute the quotient of a bignum a >= 0 and a bignum b > 0. + a is written as a = q * b + r with 0 <= r < b. q is the quotient, r + the remainder. + Finally, round-to-even is performed: If r > b/2 or if r = b/2 and q is odd, + q is incremented. + Return the allocated memory in case of success, NULL in case of memory + allocation failure. */ +static void * +divide (mpn_t a, mpn_t b, mpn_t *q) +{ + /* Algorithm: + First normalise a and b: a=[a[m-1],...,a[0]], b=[b[n-1],...,b[0]] + with m>=0 and n>0 (in base beta = 2^GMP_LIMB_BITS). + If m=n=1, perform a single-precision division: + r:=0, j:=m, + while j>0 do + {Here (q[m-1]*beta^(m-1)+...+q[j]*beta^j) * b[0] + r*beta^j = + = a[m-1]*beta^(m-1)+...+a[j]*beta^j und 0<=r=n>1, perform a multiple-precision division: + We have a/b < beta^(m-n+1). + s:=intDsize-1-(highest bit in b[n-1]), 0<=s=beta/2. + For j=m-n,...,0: {Here 0 <= r < b*beta^(j+1).} + Compute q* : + q* := floor((r[j+n]*beta+r[j+n-1])/b[n-1]). + In case of overflow (q* >= beta) set q* := beta-1. + Compute c2 := ((r[j+n]*beta+r[j+n-1]) - q* * b[n-1])*beta + r[j+n-2] + and c3 := b[n-2] * q*. + {We have 0 <= c2 < 2*beta^2, even 0 <= c2 < beta^2 if no overflow + occurred. Furthermore 0 <= c3 < beta^2. + If there was overflow and + r[j+n]*beta+r[j+n-1] - q* * b[n-1] >= beta, i.e. c2 >= beta^2, + the next test can be skipped.} + While c3 > c2, {Here 0 <= c2 < c3 < beta^2} + Put q* := q* - 1, c2 := c2 + b[n-1]*beta, c3 := c3 - b[n-2]. + If q* > 0: + Put r := r - b * q* * beta^j. In detail: + [r[n+j],...,r[j]] := [r[n+j],...,r[j]] - q* * [b[n-1],...,b[0]]. + hence: u:=0, for i:=0 to n-1 do + u := u + q* * b[i], + r[j+i]:=r[j+i]-(u mod beta) (+ beta, if carry), + u:=u div beta (+ 1, if carry in subtraction) + r[n+j]:=r[n+j]-u. + {Since always u = (q* * [b[i-1],...,b[0]] div beta^i) + 1 + < q* + 1 <= beta, + the carry u does not overflow.} + If a negative carry occurs, put q* := q* - 1 + and [r[n+j],...,r[j]] := [r[n+j],...,r[j]] + [0,b[n-1],...,b[0]]. + Set q[j] := q*. + Normalise [q[m-n],..,q[0]]; this yields the quotient q. + Shift [r[n-1],...,r[0]] right by s bits and normalise; this yields the + rest r. + The room for q[j] can be allocated at the memory location of r[n+j]. + Finally, round-to-even: + Shift r left by 1 bit. + If r > b or if r = b and q[0] is odd, q := q+1. + */ + const mp_limb_t *a_ptr = a.limbs; + size_t a_len = a.nlimbs; + const mp_limb_t *b_ptr = b.limbs; + size_t b_len = b.nlimbs; + mp_limb_t *roomptr; + mp_limb_t *tmp_roomptr = NULL; + mp_limb_t *q_ptr; + size_t q_len; + mp_limb_t *r_ptr; + size_t r_len; + + /* Allocate room for a_len+2 digits. + (Need a_len+1 digits for the real division and 1 more digit for the + final rounding of q.) */ + roomptr = (mp_limb_t *) malloc ((a_len + 2) * sizeof (mp_limb_t)); + if (roomptr == NULL) + return NULL; + + /* Normalise a. */ + while (a_len > 0 && a_ptr[a_len - 1] == 0) + a_len--; + + /* Normalise b. */ + for (;;) + { + if (b_len == 0) + /* Division by zero. */ + abort (); + if (b_ptr[b_len - 1] == 0) + b_len--; + else + break; + } + + /* Here m = a_len >= 0 and n = b_len > 0. */ + + if (a_len < b_len) + { + /* m beta^(m-2) <= a/b < beta^m */ + r_ptr = roomptr; + q_ptr = roomptr + 1; + { + mp_limb_t den = b_ptr[0]; + mp_limb_t remainder = 0; + const mp_limb_t *sourceptr = a_ptr + a_len; + mp_limb_t *destptr = q_ptr + a_len; + size_t count; + for (count = a_len; count > 0; count--) + { + mp_twolimb_t num = + ((mp_twolimb_t) remainder << GMP_LIMB_BITS) | *--sourceptr; + *--destptr = num / den; + remainder = num % den; + } + /* Normalise and store r. */ + if (remainder > 0) + { + r_ptr[0] = remainder; + r_len = 1; + } + else + r_len = 0; + /* Normalise q. */ + q_len = a_len; + if (q_ptr[q_len - 1] == 0) + q_len--; + } + } + else + { + /* n>1: multiple precision division. + beta^(m-1) <= a < beta^m, beta^(n-1) <= b < beta^n ==> + beta^(m-n-1) <= a/b < beta^(m-n+1). */ + /* Determine s. */ + size_t s; + { + mp_limb_t msd = b_ptr[b_len - 1]; /* = b[n-1], > 0 */ + s = 31; + if (msd >= 0x10000) + { + msd = msd >> 16; + s -= 16; + } + if (msd >= 0x100) + { + msd = msd >> 8; + s -= 8; + } + if (msd >= 0x10) + { + msd = msd >> 4; + s -= 4; + } + if (msd >= 0x4) + { + msd = msd >> 2; + s -= 2; + } + if (msd >= 0x2) + { + msd = msd >> 1; + s -= 1; + } + } + /* 0 <= s < GMP_LIMB_BITS. + Copy b, shifting it left by s bits. */ + if (s > 0) + { + tmp_roomptr = (mp_limb_t *) malloc (b_len * sizeof (mp_limb_t)); + if (tmp_roomptr == NULL) + { + free (roomptr); + return NULL; + } + { + const mp_limb_t *sourceptr = b_ptr; + mp_limb_t *destptr = tmp_roomptr; + mp_twolimb_t accu = 0; + size_t count; + for (count = b_len; count > 0; count--) + { + accu += (mp_twolimb_t) *sourceptr++ << s; + *destptr++ = (mp_limb_t) accu; + accu = accu >> GMP_LIMB_BITS; + } + /* accu must be zero, since that was how s was determined. */ + if (accu != 0) + abort (); + } + b_ptr = tmp_roomptr; + } + /* Copy a, shifting it left by s bits, yields r. + Memory layout: + At the beginning: r = roomptr[0..a_len], + at the end: r = roomptr[0..b_len-1], q = roomptr[b_len..a_len] */ + r_ptr = roomptr; + if (s == 0) + { + memcpy (r_ptr, a_ptr, a_len * sizeof (mp_limb_t)); + r_ptr[a_len] = 0; + } + else + { + const mp_limb_t *sourceptr = a_ptr; + mp_limb_t *destptr = r_ptr; + mp_twolimb_t accu = 0; + size_t count; + for (count = a_len; count > 0; count--) + { + accu += (mp_twolimb_t) *sourceptr++ << s; + *destptr++ = (mp_limb_t) accu; + accu = accu >> GMP_LIMB_BITS; + } + *destptr++ = (mp_limb_t) accu; + } + q_ptr = roomptr + b_len; + q_len = a_len - b_len + 1; /* q will have m-n+1 limbs */ + { + size_t j = a_len - b_len; /* m-n */ + mp_limb_t b_msd = b_ptr[b_len - 1]; /* b[n-1] */ + mp_limb_t b_2msd = b_ptr[b_len - 2]; /* b[n-2] */ + mp_twolimb_t b_msdd = /* b[n-1]*beta+b[n-2] */ + ((mp_twolimb_t) b_msd << GMP_LIMB_BITS) | b_2msd; + /* Division loop, traversed m-n+1 times. + j counts down, b is unchanged, beta/2 <= b[n-1] < beta. */ + for (;;) + { + mp_limb_t q_star; + mp_limb_t c1; + if (r_ptr[j + b_len] < b_msd) /* r[j+n] < b[n-1] ? */ + { + /* Divide r[j+n]*beta+r[j+n-1] by b[n-1], no overflow. */ + mp_twolimb_t num = + ((mp_twolimb_t) r_ptr[j + b_len] << GMP_LIMB_BITS) + | r_ptr[j + b_len - 1]; + q_star = num / b_msd; + c1 = num % b_msd; + } + else + { + /* Overflow, hence r[j+n]*beta+r[j+n-1] >= beta*b[n-1]. */ + q_star = (mp_limb_t)~(mp_limb_t)0; /* q* = beta-1 */ + /* Test whether r[j+n]*beta+r[j+n-1] - (beta-1)*b[n-1] >= beta + <==> r[j+n]*beta+r[j+n-1] + b[n-1] >= beta*b[n-1]+beta + <==> b[n-1] < floor((r[j+n]*beta+r[j+n-1]+b[n-1])/beta) + {<= beta !}. + If yes, jump directly to the subtraction loop. + (Otherwise, r[j+n]*beta+r[j+n-1] - (beta-1)*b[n-1] < beta + <==> floor((r[j+n]*beta+r[j+n-1]+b[n-1])/beta) = b[n-1] ) */ + if (r_ptr[j + b_len] > b_msd + || (c1 = r_ptr[j + b_len - 1] + b_msd) < b_msd) + /* r[j+n] >= b[n-1]+1 or + r[j+n] = b[n-1] and the addition r[j+n-1]+b[n-1] gives a + carry. */ + goto subtract; + } + /* q_star = q*, + c1 = (r[j+n]*beta+r[j+n-1]) - q* * b[n-1] (>=0, 0, decrease it by + b[n-1]*beta+b[n-2]. Because of b[n-1]*beta+b[n-2] >= beta^2/2 + this can happen only twice. */ + if (c3 > c2) + { + q_star = q_star - 1; /* q* := q* - 1 */ + if (c3 - c2 > b_msdd) + q_star = q_star - 1; /* q* := q* - 1 */ + } + } + if (q_star > 0) + subtract: + { + /* Subtract r := r - b * q* * beta^j. */ + mp_limb_t cr; + { + const mp_limb_t *sourceptr = b_ptr; + mp_limb_t *destptr = r_ptr + j; + mp_twolimb_t carry = 0; + size_t count; + for (count = b_len; count > 0; count--) + { + /* Here 0 <= carry <= q*. */ + carry = + carry + + (mp_twolimb_t) q_star * (mp_twolimb_t) *sourceptr++ + + (mp_limb_t) ~(*destptr); + /* Here 0 <= carry <= beta*q* + beta-1. */ + *destptr++ = ~(mp_limb_t) carry; + carry = carry >> GMP_LIMB_BITS; /* <= q* */ + } + cr = (mp_limb_t) carry; + } + /* Subtract cr from r_ptr[j + b_len], then forget about + r_ptr[j + b_len]. */ + if (cr > r_ptr[j + b_len]) + { + /* Subtraction gave a carry. */ + q_star = q_star - 1; /* q* := q* - 1 */ + /* Add b back. */ + { + const mp_limb_t *sourceptr = b_ptr; + mp_limb_t *destptr = r_ptr + j; + mp_limb_t carry = 0; + size_t count; + for (count = b_len; count > 0; count--) + { + mp_limb_t source1 = *sourceptr++; + mp_limb_t source2 = *destptr; + *destptr++ = source1 + source2 + carry; + carry = + (carry + ? source1 >= (mp_limb_t) ~source2 + : source1 > (mp_limb_t) ~source2); + } + } + /* Forget about the carry and about r[j+n]. */ + } + } + /* q* is determined. Store it as q[j]. */ + q_ptr[j] = q_star; + if (j == 0) + break; + j--; + } + } + r_len = b_len; + /* Normalise q. */ + if (q_ptr[q_len - 1] == 0) + q_len--; +# if 0 /* Not needed here, since we need r only to compare it with b/2, and + b is shifted left by s bits. */ + /* Shift r right by s bits. */ + if (s > 0) + { + mp_limb_t ptr = r_ptr + r_len; + mp_twolimb_t accu = 0; + size_t count; + for (count = r_len; count > 0; count--) + { + accu = (mp_twolimb_t) (mp_limb_t) accu << GMP_LIMB_BITS; + accu += (mp_twolimb_t) *--ptr << (GMP_LIMB_BITS - s); + *ptr = (mp_limb_t) (accu >> GMP_LIMB_BITS); + } + } +# endif + /* Normalise r. */ + while (r_len > 0 && r_ptr[r_len - 1] == 0) + r_len--; + } + /* Compare r << 1 with b. */ + if (r_len > b_len) + goto increment_q; + { + size_t i; + for (i = b_len;;) + { + mp_limb_t r_i = + (i <= r_len && i > 0 ? r_ptr[i - 1] >> (GMP_LIMB_BITS - 1) : 0) + | (i < r_len ? r_ptr[i] << 1 : 0); + mp_limb_t b_i = (i < b_len ? b_ptr[i] : 0); + if (r_i > b_i) + goto increment_q; + if (r_i < b_i) + goto keep_q; + if (i == 0) + break; + i--; + } + } + if (q_len > 0 && ((q_ptr[0] & 1) != 0)) + /* q is odd. */ + increment_q: + { + size_t i; + for (i = 0; i < q_len; i++) + if (++(q_ptr[i]) != 0) + goto keep_q; + q_ptr[q_len++] = 1; + } + keep_q: + if (tmp_roomptr != NULL) + free (tmp_roomptr); + q->limbs = q_ptr; + q->nlimbs = q_len; + return roomptr; +} + +/* Convert a bignum a >= 0, multiplied with 10^extra_zeroes, to decimal + representation. + Destroys the contents of a. + Return the allocated memory - containing the decimal digits in low-to-high + order, terminated with a NUL character - in case of success, NULL in case + of memory allocation failure. */ +static char * +convert_to_decimal (mpn_t a, size_t extra_zeroes) +{ + mp_limb_t *a_ptr = a.limbs; + size_t a_len = a.nlimbs; + /* 0.03345 is slightly larger than log(2)/(9*log(10)). */ + size_t c_len = 9 * ((size_t)(a_len * (GMP_LIMB_BITS * 0.03345f)) + 1); + char *c_ptr = (char *) malloc (xsum (c_len, extra_zeroes)); + if (c_ptr != NULL) + { + char *d_ptr = c_ptr; + for (; extra_zeroes > 0; extra_zeroes--) + *d_ptr++ = '0'; + while (a_len > 0) + { + /* Divide a by 10^9, in-place. */ + mp_limb_t remainder = 0; + mp_limb_t *ptr = a_ptr + a_len; + size_t count; + for (count = a_len; count > 0; count--) + { + mp_twolimb_t num = + ((mp_twolimb_t) remainder << GMP_LIMB_BITS) | *--ptr; + *ptr = num / 1000000000; + remainder = num % 1000000000; + } + /* Store the remainder as 9 decimal digits. */ + for (count = 9; count > 0; count--) + { + *d_ptr++ = '0' + (remainder % 10); + remainder = remainder / 10; + } + /* Normalize a. */ + if (a_ptr[a_len - 1] == 0) + a_len--; + } + /* Remove leading zeroes. */ + while (d_ptr > c_ptr && d_ptr[-1] == '0') + d_ptr--; + /* But keep at least one zero. */ + if (d_ptr == c_ptr) + *d_ptr++ = '0'; + /* Terminate the string. */ + *d_ptr = '\0'; + } + return c_ptr; +} + +# if NEED_PRINTF_LONG_DOUBLE + +/* Assuming x is finite and >= 0: + write x as x = 2^e * m, where m is a bignum. + Return the allocated memory in case of success, NULL in case of memory + allocation failure. */ +static void * +decode_long_double (long double x, int *ep, mpn_t *mp) +{ + mpn_t m; + int exp; + long double y; + size_t i; + + /* Allocate memory for result. */ + m.nlimbs = (LDBL_MANT_BIT + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS; + m.limbs = (mp_limb_t *) malloc (m.nlimbs * sizeof (mp_limb_t)); + if (m.limbs == NULL) + return NULL; + /* Split into exponential part and mantissa. */ + y = frexpl (x, &exp); + if (!(y >= 0.0L && y < 1.0L)) + abort (); + /* x = 2^exp * y = 2^(exp - LDBL_MANT_BIT) * (y * LDBL_MANT_BIT), and the + latter is an integer. */ + /* Convert the mantissa (y * LDBL_MANT_BIT) to a sequence of limbs. + I'm not sure whether it's safe to cast a 'long double' value between + 2^31 and 2^32 to 'unsigned int', therefore play safe and cast only + 'long double' values between 0 and 2^16 (to 'unsigned int' or 'int', + doesn't matter). */ +# if (LDBL_MANT_BIT % GMP_LIMB_BITS) != 0 +# if (LDBL_MANT_BIT % GMP_LIMB_BITS) > GMP_LIMB_BITS / 2 + { + mp_limb_t hi, lo; + y *= (mp_limb_t) 1 << (LDBL_MANT_BIT % (GMP_LIMB_BITS / 2)); + hi = (int) y; + y -= hi; + if (!(y >= 0.0L && y < 1.0L)) + abort (); + y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2); + lo = (int) y; + y -= lo; + if (!(y >= 0.0L && y < 1.0L)) + abort (); + m.limbs[LDBL_MANT_BIT / GMP_LIMB_BITS] = (hi << (GMP_LIMB_BITS / 2)) | lo; + } +# else + { + mp_limb_t d; + y *= (mp_limb_t) 1 << (LDBL_MANT_BIT % GMP_LIMB_BITS); + d = (int) y; + y -= d; + if (!(y >= 0.0L && y < 1.0L)) + abort (); + m.limbs[LDBL_MANT_BIT / GMP_LIMB_BITS] = d; + } +# endif +# endif + for (i = LDBL_MANT_BIT / GMP_LIMB_BITS; i > 0; ) + { + mp_limb_t hi, lo; + y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2); + hi = (int) y; + y -= hi; + if (!(y >= 0.0L && y < 1.0L)) + abort (); + y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2); + lo = (int) y; + y -= lo; + if (!(y >= 0.0L && y < 1.0L)) + abort (); + m.limbs[--i] = (hi << (GMP_LIMB_BITS / 2)) | lo; + } +#if 0 /* On FreeBSD 6.1/x86, 'long double' numbers sometimes have excess + precision. */ + if (!(y == 0.0L)) + abort (); +#endif + /* Normalise. */ + while (m.nlimbs > 0 && m.limbs[m.nlimbs - 1] == 0) + m.nlimbs--; + *mp = m; + *ep = exp - LDBL_MANT_BIT; + return m.limbs; +} + +# endif + +# if NEED_PRINTF_DOUBLE + +/* Assuming x is finite and >= 0: + write x as x = 2^e * m, where m is a bignum. + Return the allocated memory in case of success, NULL in case of memory + allocation failure. */ +static void * +decode_double (double x, int *ep, mpn_t *mp) +{ + mpn_t m; + int exp; + double y; + size_t i; + + /* Allocate memory for result. */ + m.nlimbs = (DBL_MANT_BIT + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS; + m.limbs = (mp_limb_t *) malloc (m.nlimbs * sizeof (mp_limb_t)); + if (m.limbs == NULL) + return NULL; + /* Split into exponential part and mantissa. */ + y = frexp (x, &exp); + if (!(y >= 0.0 && y < 1.0)) + abort (); + /* x = 2^exp * y = 2^(exp - DBL_MANT_BIT) * (y * DBL_MANT_BIT), and the + latter is an integer. */ + /* Convert the mantissa (y * DBL_MANT_BIT) to a sequence of limbs. + I'm not sure whether it's safe to cast a 'double' value between + 2^31 and 2^32 to 'unsigned int', therefore play safe and cast only + 'double' values between 0 and 2^16 (to 'unsigned int' or 'int', + doesn't matter). */ +# if (DBL_MANT_BIT % GMP_LIMB_BITS) != 0 +# if (DBL_MANT_BIT % GMP_LIMB_BITS) > GMP_LIMB_BITS / 2 + { + mp_limb_t hi, lo; + y *= (mp_limb_t) 1 << (DBL_MANT_BIT % (GMP_LIMB_BITS / 2)); + hi = (int) y; + y -= hi; + if (!(y >= 0.0 && y < 1.0)) + abort (); + y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2); + lo = (int) y; + y -= lo; + if (!(y >= 0.0 && y < 1.0)) + abort (); + m.limbs[DBL_MANT_BIT / GMP_LIMB_BITS] = (hi << (GMP_LIMB_BITS / 2)) | lo; + } +# else + { + mp_limb_t d; + y *= (mp_limb_t) 1 << (DBL_MANT_BIT % GMP_LIMB_BITS); + d = (int) y; + y -= d; + if (!(y >= 0.0 && y < 1.0)) + abort (); + m.limbs[DBL_MANT_BIT / GMP_LIMB_BITS] = d; + } +# endif +# endif + for (i = DBL_MANT_BIT / GMP_LIMB_BITS; i > 0; ) + { + mp_limb_t hi, lo; + y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2); + hi = (int) y; + y -= hi; + if (!(y >= 0.0 && y < 1.0)) + abort (); + y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2); + lo = (int) y; + y -= lo; + if (!(y >= 0.0 && y < 1.0)) + abort (); + m.limbs[--i] = (hi << (GMP_LIMB_BITS / 2)) | lo; + } + if (!(y == 0.0)) + abort (); + /* Normalise. */ + while (m.nlimbs > 0 && m.limbs[m.nlimbs - 1] == 0) + m.nlimbs--; + *mp = m; + *ep = exp - DBL_MANT_BIT; + return m.limbs; +} + +# endif + +/* Assuming x = 2^e * m is finite and >= 0, and n is an integer: + Returns the decimal representation of round (x * 10^n). + Return the allocated memory - containing the decimal digits in low-to-high + order, terminated with a NUL character - in case of success, NULL in case + of memory allocation failure. */ +static char * +scale10_round_decimal_decoded (int e, mpn_t m, void *memory, int n) +{ + int s; + size_t extra_zeroes; + unsigned int abs_n; + unsigned int abs_s; + mp_limb_t *pow5_ptr; + size_t pow5_len; + unsigned int s_limbs; + unsigned int s_bits; + mpn_t pow5; + mpn_t z; + void *z_memory; + char *digits; + + if (memory == NULL) + return NULL; + /* x = 2^e * m, hence + y = round (2^e * 10^n * m) = round (2^(e+n) * 5^n * m) + = round (2^s * 5^n * m). */ + s = e + n; + extra_zeroes = 0; + /* Factor out a common power of 10 if possible. */ + if (s > 0 && n > 0) + { + extra_zeroes = (s < n ? s : n); + s -= extra_zeroes; + n -= extra_zeroes; + } + /* Here y = round (2^s * 5^n * m) * 10^extra_zeroes. + Before converting to decimal, we need to compute + z = round (2^s * 5^n * m). */ + /* Compute 5^|n|, possibly shifted by |s| bits if n and s have the same + sign. 2.322 is slightly larger than log(5)/log(2). */ + abs_n = (n >= 0 ? n : -n); + abs_s = (s >= 0 ? s : -s); + pow5_ptr = (mp_limb_t *) malloc (((int)(abs_n * (2.322f / GMP_LIMB_BITS)) + 1 + + abs_s / GMP_LIMB_BITS + 1) + * sizeof (mp_limb_t)); + if (pow5_ptr == NULL) + { + free (memory); + return NULL; + } + /* Initialize with 1. */ + pow5_ptr[0] = 1; + pow5_len = 1; + /* Multiply with 5^|n|. */ + if (abs_n > 0) + { + static mp_limb_t const small_pow5[13 + 1] = + { + 1, 5, 25, 125, 625, 3125, 15625, 78125, 390625, 1953125, 9765625, + 48828125, 244140625, 1220703125 + }; + unsigned int n13; + for (n13 = 0; n13 <= abs_n; n13 += 13) + { + mp_limb_t digit1 = small_pow5[n13 + 13 <= abs_n ? 13 : abs_n - n13]; + size_t j; + mp_twolimb_t carry = 0; + for (j = 0; j < pow5_len; j++) + { + mp_limb_t digit2 = pow5_ptr[j]; + carry += (mp_twolimb_t) digit1 * (mp_twolimb_t) digit2; + pow5_ptr[j] = (mp_limb_t) carry; + carry = carry >> GMP_LIMB_BITS; + } + if (carry > 0) + pow5_ptr[pow5_len++] = (mp_limb_t) carry; + } + } + s_limbs = abs_s / GMP_LIMB_BITS; + s_bits = abs_s % GMP_LIMB_BITS; + if (n >= 0 ? s >= 0 : s <= 0) + { + /* Multiply with 2^|s|. */ + if (s_bits > 0) + { + mp_limb_t *ptr = pow5_ptr; + mp_twolimb_t accu = 0; + size_t count; + for (count = pow5_len; count > 0; count--) + { + accu += (mp_twolimb_t) *ptr << s_bits; + *ptr++ = (mp_limb_t) accu; + accu = accu >> GMP_LIMB_BITS; + } + if (accu > 0) + { + *ptr = (mp_limb_t) accu; + pow5_len++; + } + } + if (s_limbs > 0) + { + size_t count; + for (count = pow5_len; count > 0;) + { + count--; + pow5_ptr[s_limbs + count] = pow5_ptr[count]; + } + for (count = s_limbs; count > 0;) + { + count--; + pow5_ptr[count] = 0; + } + pow5_len += s_limbs; + } + pow5.limbs = pow5_ptr; + pow5.nlimbs = pow5_len; + if (n >= 0) + { + /* Multiply m with pow5. No division needed. */ + z_memory = multiply (m, pow5, &z); + } + else + { + /* Divide m by pow5 and round. */ + z_memory = divide (m, pow5, &z); + } + } + else + { + pow5.limbs = pow5_ptr; + pow5.nlimbs = pow5_len; + if (n >= 0) + { + /* n >= 0, s < 0. + Multiply m with pow5, then divide by 2^|s|. */ + mpn_t numerator; + mpn_t denominator; + void *tmp_memory; + tmp_memory = multiply (m, pow5, &numerator); + if (tmp_memory == NULL) + { + free (pow5_ptr); + free (memory); + return NULL; + } + /* Construct 2^|s|. */ + { + mp_limb_t *ptr = pow5_ptr + pow5_len; + size_t i; + for (i = 0; i < s_limbs; i++) + ptr[i] = 0; + ptr[s_limbs] = (mp_limb_t) 1 << s_bits; + denominator.limbs = ptr; + denominator.nlimbs = s_limbs + 1; + } + z_memory = divide (numerator, denominator, &z); + free (tmp_memory); + } + else + { + /* n < 0, s > 0. + Multiply m with 2^s, then divide by pow5. */ + mpn_t numerator; + mp_limb_t *num_ptr; + num_ptr = (mp_limb_t *) malloc ((m.nlimbs + s_limbs + 1) + * sizeof (mp_limb_t)); + if (num_ptr == NULL) + { + free (pow5_ptr); + free (memory); + return NULL; + } + { + mp_limb_t *destptr = num_ptr; + { + size_t i; + for (i = 0; i < s_limbs; i++) + *destptr++ = 0; + } + if (s_bits > 0) + { + const mp_limb_t *sourceptr = m.limbs; + mp_twolimb_t accu = 0; + size_t count; + for (count = m.nlimbs; count > 0; count--) + { + accu += (mp_twolimb_t) *sourceptr++ << s_bits; + *destptr++ = (mp_limb_t) accu; + accu = accu >> GMP_LIMB_BITS; + } + if (accu > 0) + *destptr++ = (mp_limb_t) accu; + } + else + { + const mp_limb_t *sourceptr = m.limbs; + size_t count; + for (count = m.nlimbs; count > 0; count--) + *destptr++ = *sourceptr++; + } + numerator.limbs = num_ptr; + numerator.nlimbs = destptr - num_ptr; + } + z_memory = divide (numerator, pow5, &z); + free (num_ptr); + } + } + free (pow5_ptr); + free (memory); + + /* Here y = round (x * 10^n) = z * 10^extra_zeroes. */ + + if (z_memory == NULL) + return NULL; + digits = convert_to_decimal (z, extra_zeroes); + free (z_memory); + return digits; +} + +# if NEED_PRINTF_LONG_DOUBLE + +/* Assuming x is finite and >= 0, and n is an integer: + Returns the decimal representation of round (x * 10^n). + Return the allocated memory - containing the decimal digits in low-to-high + order, terminated with a NUL character - in case of success, NULL in case + of memory allocation failure. */ +static char * +scale10_round_decimal_long_double (long double x, int n) +{ + int e IF_LINT(= 0); + mpn_t m; + void *memory = decode_long_double (x, &e, &m); + return scale10_round_decimal_decoded (e, m, memory, n); +} + +# endif + +# if NEED_PRINTF_DOUBLE + +/* Assuming x is finite and >= 0, and n is an integer: + Returns the decimal representation of round (x * 10^n). + Return the allocated memory - containing the decimal digits in low-to-high + order, terminated with a NUL character - in case of success, NULL in case + of memory allocation failure. */ +static char * +scale10_round_decimal_double (double x, int n) +{ + int e IF_LINT(= 0); + mpn_t m; + void *memory = decode_double (x, &e, &m); + return scale10_round_decimal_decoded (e, m, memory, n); +} + +# endif + +# if NEED_PRINTF_LONG_DOUBLE + +/* Assuming x is finite and > 0: + Return an approximation for n with 10^n <= x < 10^(n+1). + The approximation is usually the right n, but may be off by 1 sometimes. */ +static int +floorlog10l (long double x) +{ + int exp; + long double y; + double z; + double l; + + /* Split into exponential part and mantissa. */ + y = frexpl (x, &exp); + if (!(y >= 0.0L && y < 1.0L)) + abort (); + if (y == 0.0L) + return INT_MIN; + if (y < 0.5L) + { + while (y < (1.0L / (1 << (GMP_LIMB_BITS / 2)) / (1 << (GMP_LIMB_BITS / 2)))) + { + y *= 1.0L * (1 << (GMP_LIMB_BITS / 2)) * (1 << (GMP_LIMB_BITS / 2)); + exp -= GMP_LIMB_BITS; + } + if (y < (1.0L / (1 << 16))) + { + y *= 1.0L * (1 << 16); + exp -= 16; + } + if (y < (1.0L / (1 << 8))) + { + y *= 1.0L * (1 << 8); + exp -= 8; + } + if (y < (1.0L / (1 << 4))) + { + y *= 1.0L * (1 << 4); + exp -= 4; + } + if (y < (1.0L / (1 << 2))) + { + y *= 1.0L * (1 << 2); + exp -= 2; + } + if (y < (1.0L / (1 << 1))) + { + y *= 1.0L * (1 << 1); + exp -= 1; + } + } + if (!(y >= 0.5L && y < 1.0L)) + abort (); + /* Compute an approximation for l = log2(x) = exp + log2(y). */ + l = exp; + z = y; + if (z < 0.70710678118654752444) + { + z *= 1.4142135623730950488; + l -= 0.5; + } + if (z < 0.8408964152537145431) + { + z *= 1.1892071150027210667; + l -= 0.25; + } + if (z < 0.91700404320467123175) + { + z *= 1.0905077326652576592; + l -= 0.125; + } + if (z < 0.9576032806985736469) + { + z *= 1.0442737824274138403; + l -= 0.0625; + } + /* Now 0.95 <= z <= 1.01. */ + z = 1 - z; + /* log2(1-z) = 1/log(2) * (- z - z^2/2 - z^3/3 - z^4/4 - ...) + Four terms are enough to get an approximation with error < 10^-7. */ + l -= 1.4426950408889634074 * z * (1.0 + z * (0.5 + z * ((1.0 / 3) + z * 0.25))); + /* Finally multiply with log(2)/log(10), yields an approximation for + log10(x). */ + l *= 0.30102999566398119523; + /* Round down to the next integer. */ + return (int) l + (l < 0 ? -1 : 0); +} + +# endif + +# if NEED_PRINTF_DOUBLE + +/* Assuming x is finite and > 0: + Return an approximation for n with 10^n <= x < 10^(n+1). + The approximation is usually the right n, but may be off by 1 sometimes. */ +static int +floorlog10 (double x) +{ + int exp; + double y; + double z; + double l; + + /* Split into exponential part and mantissa. */ + y = frexp (x, &exp); + if (!(y >= 0.0 && y < 1.0)) + abort (); + if (y == 0.0) + return INT_MIN; + if (y < 0.5) + { + while (y < (1.0 / (1 << (GMP_LIMB_BITS / 2)) / (1 << (GMP_LIMB_BITS / 2)))) + { + y *= 1.0 * (1 << (GMP_LIMB_BITS / 2)) * (1 << (GMP_LIMB_BITS / 2)); + exp -= GMP_LIMB_BITS; + } + if (y < (1.0 / (1 << 16))) + { + y *= 1.0 * (1 << 16); + exp -= 16; + } + if (y < (1.0 / (1 << 8))) + { + y *= 1.0 * (1 << 8); + exp -= 8; + } + if (y < (1.0 / (1 << 4))) + { + y *= 1.0 * (1 << 4); + exp -= 4; + } + if (y < (1.0 / (1 << 2))) + { + y *= 1.0 * (1 << 2); + exp -= 2; + } + if (y < (1.0 / (1 << 1))) + { + y *= 1.0 * (1 << 1); + exp -= 1; + } + } + if (!(y >= 0.5 && y < 1.0)) + abort (); + /* Compute an approximation for l = log2(x) = exp + log2(y). */ + l = exp; + z = y; + if (z < 0.70710678118654752444) + { + z *= 1.4142135623730950488; + l -= 0.5; + } + if (z < 0.8408964152537145431) + { + z *= 1.1892071150027210667; + l -= 0.25; + } + if (z < 0.91700404320467123175) + { + z *= 1.0905077326652576592; + l -= 0.125; + } + if (z < 0.9576032806985736469) + { + z *= 1.0442737824274138403; + l -= 0.0625; + } + /* Now 0.95 <= z <= 1.01. */ + z = 1 - z; + /* log2(1-z) = 1/log(2) * (- z - z^2/2 - z^3/3 - z^4/4 - ...) + Four terms are enough to get an approximation with error < 10^-7. */ + l -= 1.4426950408889634074 * z * (1.0 + z * (0.5 + z * ((1.0 / 3) + z * 0.25))); + /* Finally multiply with log(2)/log(10), yields an approximation for + log10(x). */ + l *= 0.30102999566398119523; + /* Round down to the next integer. */ + return (int) l + (l < 0 ? -1 : 0); +} + +# endif + +/* Tests whether a string of digits consists of exactly PRECISION zeroes and + a single '1' digit. */ +static int +is_borderline (const char *digits, size_t precision) +{ + for (; precision > 0; precision--, digits++) + if (*digits != '0') + return 0; + if (*digits != '1') + return 0; + digits++; + return *digits == '\0'; +} + +#endif + +DCHAR_T * +VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, + const FCHAR_T *format, va_list args) +{ + DIRECTIVES d; + arguments a; + + if (PRINTF_PARSE (format, &d, &a) < 0) + /* errno is already set. */ + return NULL; + +#define CLEANUP() \ + free (d.dir); \ + if (a.arg) \ + free (a.arg); + + if (PRINTF_FETCHARGS (args, &a) < 0) + { + CLEANUP (); + errno = EINVAL; + return NULL; + } + + { + size_t buf_neededlength; + TCHAR_T *buf; + TCHAR_T *buf_malloced; + const FCHAR_T *cp; + size_t i; + DIRECTIVE *dp; + /* Output string accumulator. */ + DCHAR_T *result; + size_t allocated; + size_t length; + + /* Allocate a small buffer that will hold a directive passed to + sprintf or snprintf. */ + buf_neededlength = + xsum4 (7, d.max_width_length, d.max_precision_length, 6); +#if HAVE_ALLOCA + if (buf_neededlength < 4000 / sizeof (TCHAR_T)) + { + buf = (TCHAR_T *) alloca (buf_neededlength * sizeof (TCHAR_T)); + buf_malloced = NULL; + } + else +#endif + { + size_t buf_memsize = xtimes (buf_neededlength, sizeof (TCHAR_T)); + if (size_overflow_p (buf_memsize)) + goto out_of_memory_1; + buf = (TCHAR_T *) malloc (buf_memsize); + if (buf == NULL) + goto out_of_memory_1; + buf_malloced = buf; + } + + if (resultbuf != NULL) + { + result = resultbuf; + allocated = *lengthp; + } + else + { + result = NULL; + allocated = 0; + } + length = 0; + /* Invariants: + result is either == resultbuf or == NULL or malloc-allocated. + If length > 0, then result != NULL. */ + + /* Ensures that allocated >= needed. Aborts through a jump to + out_of_memory if needed is SIZE_MAX or otherwise too big. */ +#define ENSURE_ALLOCATION(needed) \ + if ((needed) > allocated) \ + { \ + size_t memory_size; \ + DCHAR_T *memory; \ + \ + allocated = (allocated > 0 ? xtimes (allocated, 2) : 12); \ + if ((needed) > allocated) \ + allocated = (needed); \ + memory_size = xtimes (allocated, sizeof (DCHAR_T)); \ + if (size_overflow_p (memory_size)) \ + goto out_of_memory; \ + if (result == resultbuf || result == NULL) \ + memory = (DCHAR_T *) malloc (memory_size); \ + else \ + memory = (DCHAR_T *) realloc (result, memory_size); \ + if (memory == NULL) \ + goto out_of_memory; \ + if (result == resultbuf && length > 0) \ + DCHAR_CPY (memory, result, length); \ + result = memory; \ + } + + for (cp = format, i = 0, dp = &d.dir[0]; ; cp = dp->dir_end, i++, dp++) + { + if (cp != dp->dir_start) + { + size_t n = dp->dir_start - cp; + size_t augmented_length = xsum (length, n); + + ENSURE_ALLOCATION (augmented_length); + /* This copies a piece of FCHAR_T[] into a DCHAR_T[]. Here we + need that the format string contains only ASCII characters + if FCHAR_T and DCHAR_T are not the same type. */ + if (sizeof (FCHAR_T) == sizeof (DCHAR_T)) + { + DCHAR_CPY (result + length, (const DCHAR_T *) cp, n); + length = augmented_length; + } + else + { + do + result[length++] = (unsigned char) *cp++; + while (--n > 0); + } + } + if (i == d.count) + break; + + /* Execute a single directive. */ + if (dp->conversion == '%') + { + size_t augmented_length; + + if (!(dp->arg_index == ARG_NONE)) + abort (); + augmented_length = xsum (length, 1); + ENSURE_ALLOCATION (augmented_length); + result[length] = '%'; + length = augmented_length; + } + else + { + if (!(dp->arg_index != ARG_NONE)) + abort (); + + if (dp->conversion == 'n') + { + switch (a.arg[dp->arg_index].type) + { + case TYPE_COUNT_SCHAR_POINTER: + *a.arg[dp->arg_index].a.a_count_schar_pointer = length; + break; + case TYPE_COUNT_SHORT_POINTER: + *a.arg[dp->arg_index].a.a_count_short_pointer = length; + break; + case TYPE_COUNT_INT_POINTER: + *a.arg[dp->arg_index].a.a_count_int_pointer = length; + break; + case TYPE_COUNT_LONGINT_POINTER: + *a.arg[dp->arg_index].a.a_count_longint_pointer = length; + break; +#if HAVE_LONG_LONG_INT + case TYPE_COUNT_LONGLONGINT_POINTER: + *a.arg[dp->arg_index].a.a_count_longlongint_pointer = length; + break; +#endif + default: + abort (); + } + } +#if ENABLE_UNISTDIO + /* The unistdio extensions. */ + else if (dp->conversion == 'U') + { + arg_type type = a.arg[dp->arg_index].type; + int flags = dp->flags; + int has_width; + size_t width; + int has_precision; + size_t precision; + + has_width = 0; + width = 0; + if (dp->width_start != dp->width_end) + { + if (dp->width_arg_index != ARG_NONE) + { + int arg; + + if (!(a.arg[dp->width_arg_index].type == TYPE_INT)) + abort (); + arg = a.arg[dp->width_arg_index].a.a_int; + if (arg < 0) + { + /* "A negative field width is taken as a '-' flag + followed by a positive field width." */ + flags |= FLAG_LEFT; + width = (unsigned int) (-arg); + } + else + width = arg; + } + else + { + const FCHAR_T *digitp = dp->width_start; + + do + width = xsum (xtimes (width, 10), *digitp++ - '0'); + while (digitp != dp->width_end); + } + has_width = 1; + } + + has_precision = 0; + precision = 0; + if (dp->precision_start != dp->precision_end) + { + if (dp->precision_arg_index != ARG_NONE) + { + int arg; + + if (!(a.arg[dp->precision_arg_index].type == TYPE_INT)) + abort (); + arg = a.arg[dp->precision_arg_index].a.a_int; + /* "A negative precision is taken as if the precision + were omitted." */ + if (arg >= 0) + { + precision = arg; + has_precision = 1; + } + } + else + { + const FCHAR_T *digitp = dp->precision_start + 1; + + precision = 0; + while (digitp != dp->precision_end) + precision = xsum (xtimes (precision, 10), *digitp++ - '0'); + has_precision = 1; + } + } + + switch (type) + { + case TYPE_U8_STRING: + { + const uint8_t *arg = a.arg[dp->arg_index].a.a_u8_string; + const uint8_t *arg_end; + size_t characters; + + if (has_precision) + { + /* Use only PRECISION characters, from the left. */ + arg_end = arg; + characters = 0; + for (; precision > 0; precision--) + { + int count = u8_strmblen (arg_end); + if (count == 0) + break; + if (count < 0) + { + if (!(result == resultbuf || result == NULL)) + free (result); + if (buf_malloced != NULL) + free (buf_malloced); + CLEANUP (); + errno = EILSEQ; + return NULL; + } + arg_end += count; + characters++; + } + } + else if (has_width) + { + /* Use the entire string, and count the number of + characters. */ + arg_end = arg; + characters = 0; + for (;;) + { + int count = u8_strmblen (arg_end); + if (count == 0) + break; + if (count < 0) + { + if (!(result == resultbuf || result == NULL)) + free (result); + if (buf_malloced != NULL) + free (buf_malloced); + CLEANUP (); + errno = EILSEQ; + return NULL; + } + arg_end += count; + characters++; + } + } + else + { + /* Use the entire string. */ + arg_end = arg + u8_strlen (arg); + /* The number of characters doesn't matter. */ + characters = 0; + } + + if (has_width && width > characters + && !(dp->flags & FLAG_LEFT)) + { + size_t n = width - characters; + ENSURE_ALLOCATION (xsum (length, n)); + DCHAR_SET (result + length, ' ', n); + length += n; + } + +# if DCHAR_IS_UINT8_T + { + size_t n = arg_end - arg; + ENSURE_ALLOCATION (xsum (length, n)); + DCHAR_CPY (result + length, arg, n); + length += n; + } +# else + { /* Convert. */ + DCHAR_T *converted = result + length; + size_t converted_len = allocated - length; +# if DCHAR_IS_TCHAR + /* Convert from UTF-8 to locale encoding. */ + converted = + u8_conv_to_encoding (locale_charset (), + iconveh_question_mark, + arg, arg_end - arg, NULL, + converted, &converted_len); +# else + /* Convert from UTF-8 to UTF-16/UTF-32. */ + converted = + U8_TO_DCHAR (arg, arg_end - arg, + converted, &converted_len); +# endif + if (converted == NULL) + { + int saved_errno = errno; + if (!(result == resultbuf || result == NULL)) + free (result); + if (buf_malloced != NULL) + free (buf_malloced); + CLEANUP (); + errno = saved_errno; + return NULL; + } + if (converted != result + length) + { + ENSURE_ALLOCATION (xsum (length, converted_len)); + DCHAR_CPY (result + length, converted, converted_len); + free (converted); + } + length += converted_len; + } +# endif + + if (has_width && width > characters + && (dp->flags & FLAG_LEFT)) + { + size_t n = width - characters; + ENSURE_ALLOCATION (xsum (length, n)); + DCHAR_SET (result + length, ' ', n); + length += n; + } + } + break; + + case TYPE_U16_STRING: + { + const uint16_t *arg = a.arg[dp->arg_index].a.a_u16_string; + const uint16_t *arg_end; + size_t characters; + + if (has_precision) + { + /* Use only PRECISION characters, from the left. */ + arg_end = arg; + characters = 0; + for (; precision > 0; precision--) + { + int count = u16_strmblen (arg_end); + if (count == 0) + break; + if (count < 0) + { + if (!(result == resultbuf || result == NULL)) + free (result); + if (buf_malloced != NULL) + free (buf_malloced); + CLEANUP (); + errno = EILSEQ; + return NULL; + } + arg_end += count; + characters++; + } + } + else if (has_width) + { + /* Use the entire string, and count the number of + characters. */ + arg_end = arg; + characters = 0; + for (;;) + { + int count = u16_strmblen (arg_end); + if (count == 0) + break; + if (count < 0) + { + if (!(result == resultbuf || result == NULL)) + free (result); + if (buf_malloced != NULL) + free (buf_malloced); + CLEANUP (); + errno = EILSEQ; + return NULL; + } + arg_end += count; + characters++; + } + } + else + { + /* Use the entire string. */ + arg_end = arg + u16_strlen (arg); + /* The number of characters doesn't matter. */ + characters = 0; + } + + if (has_width && width > characters + && !(dp->flags & FLAG_LEFT)) + { + size_t n = width - characters; + ENSURE_ALLOCATION (xsum (length, n)); + DCHAR_SET (result + length, ' ', n); + length += n; + } + +# if DCHAR_IS_UINT16_T + { + size_t n = arg_end - arg; + ENSURE_ALLOCATION (xsum (length, n)); + DCHAR_CPY (result + length, arg, n); + length += n; + } +# else + { /* Convert. */ + DCHAR_T *converted = result + length; + size_t converted_len = allocated - length; +# if DCHAR_IS_TCHAR + /* Convert from UTF-16 to locale encoding. */ + converted = + u16_conv_to_encoding (locale_charset (), + iconveh_question_mark, + arg, arg_end - arg, NULL, + converted, &converted_len); +# else + /* Convert from UTF-16 to UTF-8/UTF-32. */ + converted = + U16_TO_DCHAR (arg, arg_end - arg, + converted, &converted_len); +# endif + if (converted == NULL) + { + int saved_errno = errno; + if (!(result == resultbuf || result == NULL)) + free (result); + if (buf_malloced != NULL) + free (buf_malloced); + CLEANUP (); + errno = saved_errno; + return NULL; + } + if (converted != result + length) + { + ENSURE_ALLOCATION (xsum (length, converted_len)); + DCHAR_CPY (result + length, converted, converted_len); + free (converted); + } + length += converted_len; + } +# endif + + if (has_width && width > characters + && (dp->flags & FLAG_LEFT)) + { + size_t n = width - characters; + ENSURE_ALLOCATION (xsum (length, n)); + DCHAR_SET (result + length, ' ', n); + length += n; + } + } + break; + + case TYPE_U32_STRING: + { + const uint32_t *arg = a.arg[dp->arg_index].a.a_u32_string; + const uint32_t *arg_end; + size_t characters; + + if (has_precision) + { + /* Use only PRECISION characters, from the left. */ + arg_end = arg; + characters = 0; + for (; precision > 0; precision--) + { + int count = u32_strmblen (arg_end); + if (count == 0) + break; + if (count < 0) + { + if (!(result == resultbuf || result == NULL)) + free (result); + if (buf_malloced != NULL) + free (buf_malloced); + CLEANUP (); + errno = EILSEQ; + return NULL; + } + arg_end += count; + characters++; + } + } + else if (has_width) + { + /* Use the entire string, and count the number of + characters. */ + arg_end = arg; + characters = 0; + for (;;) + { + int count = u32_strmblen (arg_end); + if (count == 0) + break; + if (count < 0) + { + if (!(result == resultbuf || result == NULL)) + free (result); + if (buf_malloced != NULL) + free (buf_malloced); + CLEANUP (); + errno = EILSEQ; + return NULL; + } + arg_end += count; + characters++; + } + } + else + { + /* Use the entire string. */ + arg_end = arg + u32_strlen (arg); + /* The number of characters doesn't matter. */ + characters = 0; + } + + if (has_width && width > characters + && !(dp->flags & FLAG_LEFT)) + { + size_t n = width - characters; + ENSURE_ALLOCATION (xsum (length, n)); + DCHAR_SET (result + length, ' ', n); + length += n; + } + +# if DCHAR_IS_UINT32_T + { + size_t n = arg_end - arg; + ENSURE_ALLOCATION (xsum (length, n)); + DCHAR_CPY (result + length, arg, n); + length += n; + } +# else + { /* Convert. */ + DCHAR_T *converted = result + length; + size_t converted_len = allocated - length; +# if DCHAR_IS_TCHAR + /* Convert from UTF-32 to locale encoding. */ + converted = + u32_conv_to_encoding (locale_charset (), + iconveh_question_mark, + arg, arg_end - arg, NULL, + converted, &converted_len); +# else + /* Convert from UTF-32 to UTF-8/UTF-16. */ + converted = + U32_TO_DCHAR (arg, arg_end - arg, + converted, &converted_len); +# endif + if (converted == NULL) + { + int saved_errno = errno; + if (!(result == resultbuf || result == NULL)) + free (result); + if (buf_malloced != NULL) + free (buf_malloced); + CLEANUP (); + errno = saved_errno; + return NULL; + } + if (converted != result + length) + { + ENSURE_ALLOCATION (xsum (length, converted_len)); + DCHAR_CPY (result + length, converted, converted_len); + free (converted); + } + length += converted_len; + } +# endif + + if (has_width && width > characters + && (dp->flags & FLAG_LEFT)) + { + size_t n = width - characters; + ENSURE_ALLOCATION (xsum (length, n)); + DCHAR_SET (result + length, ' ', n); + length += n; + } + } + break; + + default: + abort (); + } + } +#endif +#if (!USE_SNPRINTF || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL)) && HAVE_WCHAR_T + else if (dp->conversion == 's' +# if WIDE_CHAR_VERSION + && a.arg[dp->arg_index].type != TYPE_WIDE_STRING +# else + && a.arg[dp->arg_index].type == TYPE_WIDE_STRING +# endif + ) + { + /* The normal handling of the 's' directive below requires + allocating a temporary buffer. The determination of its + length (tmp_length), in the case when a precision is + specified, below requires a conversion between a char[] + string and a wchar_t[] wide string. It could be done, but + we have no guarantee that the implementation of sprintf will + use the exactly same algorithm. Without this guarantee, it + is possible to have buffer overrun bugs. In order to avoid + such bugs, we implement the entire processing of the 's' + directive ourselves. */ + int flags = dp->flags; + int has_width; + size_t width; + int has_precision; + size_t precision; + + has_width = 0; + width = 0; + if (dp->width_start != dp->width_end) + { + if (dp->width_arg_index != ARG_NONE) + { + int arg; + + if (!(a.arg[dp->width_arg_index].type == TYPE_INT)) + abort (); + arg = a.arg[dp->width_arg_index].a.a_int; + if (arg < 0) + { + /* "A negative field width is taken as a '-' flag + followed by a positive field width." */ + flags |= FLAG_LEFT; + width = (unsigned int) (-arg); + } + else + width = arg; + } + else + { + const FCHAR_T *digitp = dp->width_start; + + do + width = xsum (xtimes (width, 10), *digitp++ - '0'); + while (digitp != dp->width_end); + } + has_width = 1; + } + + has_precision = 0; + precision = 6; + if (dp->precision_start != dp->precision_end) + { + if (dp->precision_arg_index != ARG_NONE) + { + int arg; + + if (!(a.arg[dp->precision_arg_index].type == TYPE_INT)) + abort (); + arg = a.arg[dp->precision_arg_index].a.a_int; + /* "A negative precision is taken as if the precision + were omitted." */ + if (arg >= 0) + { + precision = arg; + has_precision = 1; + } + } + else + { + const FCHAR_T *digitp = dp->precision_start + 1; + + precision = 0; + while (digitp != dp->precision_end) + precision = xsum (xtimes (precision, 10), *digitp++ - '0'); + has_precision = 1; + } + } + +# if WIDE_CHAR_VERSION + /* %s in vasnwprintf. See the specification of fwprintf. */ + { + const char *arg = a.arg[dp->arg_index].a.a_string; + const char *arg_end; + size_t characters; + + if (has_precision) + { + /* Use only as many bytes as needed to produce PRECISION + wide characters, from the left. */ +# if HAVE_MBRTOWC + mbstate_t state; + memset (&state, '\0', sizeof (mbstate_t)); +# endif + arg_end = arg; + characters = 0; + for (; precision > 0; precision--) + { + int count; +# if HAVE_MBRTOWC + count = mbrlen (arg_end, MB_CUR_MAX, &state); +# else + count = mblen (arg_end, MB_CUR_MAX); +# endif + if (count == 0) + /* Found the terminating NUL. */ + break; + if (count < 0) + { + /* Invalid or incomplete multibyte character. */ + if (!(result == resultbuf || result == NULL)) + free (result); + if (buf_malloced != NULL) + free (buf_malloced); + CLEANUP (); + errno = EILSEQ; + return NULL; + } + arg_end += count; + characters++; + } + } + else if (has_width) + { + /* Use the entire string, and count the number of wide + characters. */ +# if HAVE_MBRTOWC + mbstate_t state; + memset (&state, '\0', sizeof (mbstate_t)); +# endif + arg_end = arg; + characters = 0; + for (;;) + { + int count; +# if HAVE_MBRTOWC + count = mbrlen (arg_end, MB_CUR_MAX, &state); +# else + count = mblen (arg_end, MB_CUR_MAX); +# endif + if (count == 0) + /* Found the terminating NUL. */ + break; + if (count < 0) + { + /* Invalid or incomplete multibyte character. */ + if (!(result == resultbuf || result == NULL)) + free (result); + if (buf_malloced != NULL) + free (buf_malloced); + CLEANUP (); + errno = EILSEQ; + return NULL; + } + arg_end += count; + characters++; + } + } + else + { + /* Use the entire string. */ + arg_end = arg + strlen (arg); + /* The number of characters doesn't matter. */ + characters = 0; + } + + if (has_width && width > characters + && !(dp->flags & FLAG_LEFT)) + { + size_t n = width - characters; + ENSURE_ALLOCATION (xsum (length, n)); + DCHAR_SET (result + length, ' ', n); + length += n; + } + + if (has_precision || has_width) + { + /* We know the number of wide characters in advance. */ + size_t remaining; +# if HAVE_MBRTOWC + mbstate_t state; + memset (&state, '\0', sizeof (mbstate_t)); +# endif + ENSURE_ALLOCATION (xsum (length, characters)); + for (remaining = characters; remaining > 0; remaining--) + { + wchar_t wc; + int count; +# if HAVE_MBRTOWC + count = mbrtowc (&wc, arg, arg_end - arg, &state); +# else + count = mbtowc (&wc, arg, arg_end - arg); +# endif + if (count <= 0) + /* mbrtowc not consistent with mbrlen, or mbtowc + not consistent with mblen. */ + abort (); + result[length++] = wc; + arg += count; + } + if (!(arg == arg_end)) + abort (); + } + else + { +# if HAVE_MBRTOWC + mbstate_t state; + memset (&state, '\0', sizeof (mbstate_t)); +# endif + while (arg < arg_end) + { + wchar_t wc; + int count; +# if HAVE_MBRTOWC + count = mbrtowc (&wc, arg, arg_end - arg, &state); +# else + count = mbtowc (&wc, arg, arg_end - arg); +# endif + if (count <= 0) + /* mbrtowc not consistent with mbrlen, or mbtowc + not consistent with mblen. */ + abort (); + ENSURE_ALLOCATION (xsum (length, 1)); + result[length++] = wc; + arg += count; + } + } + + if (has_width && width > characters + && (dp->flags & FLAG_LEFT)) + { + size_t n = width - characters; + ENSURE_ALLOCATION (xsum (length, n)); + DCHAR_SET (result + length, ' ', n); + length += n; + } + } +# else + /* %ls in vasnprintf. See the specification of fprintf. */ + { + const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string; + const wchar_t *arg_end; + size_t characters; +# if !DCHAR_IS_TCHAR + /* This code assumes that TCHAR_T is 'char'. */ + typedef int TCHAR_T_verify[2 * (sizeof (TCHAR_T) == 1) - 1]; + TCHAR_T *tmpsrc; + DCHAR_T *tmpdst; + size_t tmpdst_len; +# endif + size_t w; + + if (has_precision) + { + /* Use only as many wide characters as needed to produce + at most PRECISION bytes, from the left. */ +# if HAVE_WCRTOMB + mbstate_t state; + memset (&state, '\0', sizeof (mbstate_t)); +# endif + arg_end = arg; + characters = 0; + while (precision > 0) + { + char buf[64]; /* Assume MB_CUR_MAX <= 64. */ + int count; + + if (*arg_end == 0) + /* Found the terminating null wide character. */ + break; +# if HAVE_WCRTOMB + count = wcrtomb (buf, *arg_end, &state); +# else + count = wctomb (buf, *arg_end); +# endif + if (count < 0) + { + /* Cannot convert. */ + if (!(result == resultbuf || result == NULL)) + free (result); + if (buf_malloced != NULL) + free (buf_malloced); + CLEANUP (); + errno = EILSEQ; + return NULL; + } + if (precision < count) + break; + arg_end++; + characters += count; + precision -= count; + } + } +# if DCHAR_IS_TCHAR + else if (has_width) +# else + else +# endif + { + /* Use the entire string, and count the number of + bytes. */ +# if HAVE_WCRTOMB + mbstate_t state; + memset (&state, '\0', sizeof (mbstate_t)); +# endif + arg_end = arg; + characters = 0; + for (;;) + { + char buf[64]; /* Assume MB_CUR_MAX <= 64. */ + int count; + + if (*arg_end == 0) + /* Found the terminating null wide character. */ + break; +# if HAVE_WCRTOMB + count = wcrtomb (buf, *arg_end, &state); +# else + count = wctomb (buf, *arg_end); +# endif + if (count < 0) + { + /* Cannot convert. */ + if (!(result == resultbuf || result == NULL)) + free (result); + if (buf_malloced != NULL) + free (buf_malloced); + CLEANUP (); + errno = EILSEQ; + return NULL; + } + arg_end++; + characters += count; + } + } +# if DCHAR_IS_TCHAR + else + { + /* Use the entire string. */ + arg_end = arg + local_wcslen (arg); + /* The number of bytes doesn't matter. */ + characters = 0; + } +# endif + +# if !DCHAR_IS_TCHAR + /* Convert the string into a piece of temporary memory. */ + tmpsrc = (TCHAR_T *) malloc (characters * sizeof (TCHAR_T)); + if (tmpsrc == NULL) + goto out_of_memory; + { + TCHAR_T *tmpptr = tmpsrc; + size_t remaining; +# if HAVE_WCRTOMB + mbstate_t state; + memset (&state, '\0', sizeof (mbstate_t)); +# endif + for (remaining = characters; remaining > 0; ) + { + char buf[64]; /* Assume MB_CUR_MAX <= 64. */ + int count; + + if (*arg == 0) + abort (); +# if HAVE_WCRTOMB + count = wcrtomb (buf, *arg, &state); +# else + count = wctomb (buf, *arg); +# endif + if (count <= 0) + /* Inconsistency. */ + abort (); + memcpy (tmpptr, buf, count); + tmpptr += count; + arg++; + remaining -= count; + } + if (!(arg == arg_end)) + abort (); + } + + /* Convert from TCHAR_T[] to DCHAR_T[]. */ + tmpdst = + DCHAR_CONV_FROM_ENCODING (locale_charset (), + iconveh_question_mark, + tmpsrc, characters, + NULL, + NULL, &tmpdst_len); + if (tmpdst == NULL) + { + int saved_errno = errno; + free (tmpsrc); + if (!(result == resultbuf || result == NULL)) + free (result); + if (buf_malloced != NULL) + free (buf_malloced); + CLEANUP (); + errno = saved_errno; + return NULL; + } + free (tmpsrc); +# endif + + if (has_width) + { +# if ENABLE_UNISTDIO + /* Outside POSIX, it's preferrable to compare the width + against the number of _characters_ of the converted + value. */ + w = DCHAR_MBSNLEN (result + length, characters); +# else + /* The width is compared against the number of _bytes_ + of the converted value, says POSIX. */ + w = characters; +# endif + } + else + /* w doesn't matter. */ + w = 0; + + if (has_width && width > w + && !(dp->flags & FLAG_LEFT)) + { + size_t n = width - w; + ENSURE_ALLOCATION (xsum (length, n)); + DCHAR_SET (result + length, ' ', n); + length += n; + } + +# if DCHAR_IS_TCHAR + if (has_precision || has_width) + { + /* We know the number of bytes in advance. */ + size_t remaining; +# if HAVE_WCRTOMB + mbstate_t state; + memset (&state, '\0', sizeof (mbstate_t)); +# endif + ENSURE_ALLOCATION (xsum (length, characters)); + for (remaining = characters; remaining > 0; ) + { + char buf[64]; /* Assume MB_CUR_MAX <= 64. */ + int count; + + if (*arg == 0) + abort (); +# if HAVE_WCRTOMB + count = wcrtomb (buf, *arg, &state); +# else + count = wctomb (buf, *arg); +# endif + if (count <= 0) + /* Inconsistency. */ + abort (); + memcpy (result + length, buf, count); + length += count; + arg++; + remaining -= count; + } + if (!(arg == arg_end)) + abort (); + } + else + { +# if HAVE_WCRTOMB + mbstate_t state; + memset (&state, '\0', sizeof (mbstate_t)); +# endif + while (arg < arg_end) + { + char buf[64]; /* Assume MB_CUR_MAX <= 64. */ + int count; + + if (*arg == 0) + abort (); +# if HAVE_WCRTOMB + count = wcrtomb (buf, *arg, &state); +# else + count = wctomb (buf, *arg); +# endif + if (count <= 0) + /* Inconsistency. */ + abort (); + ENSURE_ALLOCATION (xsum (length, count)); + memcpy (result + length, buf, count); + length += count; + arg++; + } + } +# else + ENSURE_ALLOCATION (xsum (length, tmpdst_len)); + DCHAR_CPY (result + length, tmpdst, tmpdst_len); + free (tmpdst); + length += tmpdst_len; +# endif + + if (has_width && width > w + && (dp->flags & FLAG_LEFT)) + { + size_t n = width - w; + ENSURE_ALLOCATION (xsum (length, n)); + DCHAR_SET (result + length, ' ', n); + length += n; + } + } + } +# endif +#endif +#if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL + else if ((dp->conversion == 'a' || dp->conversion == 'A') +# if !(NEED_PRINTF_DIRECTIVE_A || (NEED_PRINTF_LONG_DOUBLE && NEED_PRINTF_DOUBLE)) + && (0 +# if NEED_PRINTF_DOUBLE + || a.arg[dp->arg_index].type == TYPE_DOUBLE +# endif +# if NEED_PRINTF_LONG_DOUBLE + || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE +# endif + ) +# endif + ) + { + arg_type type = a.arg[dp->arg_index].type; + int flags = dp->flags; + int has_width; + size_t width; + int has_precision; + size_t precision; + size_t tmp_length; + DCHAR_T tmpbuf[700]; + DCHAR_T *tmp; + DCHAR_T *pad_ptr; + DCHAR_T *p; + + has_width = 0; + width = 0; + if (dp->width_start != dp->width_end) + { + if (dp->width_arg_index != ARG_NONE) + { + int arg; + + if (!(a.arg[dp->width_arg_index].type == TYPE_INT)) + abort (); + arg = a.arg[dp->width_arg_index].a.a_int; + if (arg < 0) + { + /* "A negative field width is taken as a '-' flag + followed by a positive field width." */ + flags |= FLAG_LEFT; + width = (unsigned int) (-arg); + } + else + width = arg; + } + else + { + const FCHAR_T *digitp = dp->width_start; + + do + width = xsum (xtimes (width, 10), *digitp++ - '0'); + while (digitp != dp->width_end); + } + has_width = 1; + } + + has_precision = 0; + precision = 0; + if (dp->precision_start != dp->precision_end) + { + if (dp->precision_arg_index != ARG_NONE) + { + int arg; + + if (!(a.arg[dp->precision_arg_index].type == TYPE_INT)) + abort (); + arg = a.arg[dp->precision_arg_index].a.a_int; + /* "A negative precision is taken as if the precision + were omitted." */ + if (arg >= 0) + { + precision = arg; + has_precision = 1; + } + } + else + { + const FCHAR_T *digitp = dp->precision_start + 1; + + precision = 0; + while (digitp != dp->precision_end) + precision = xsum (xtimes (precision, 10), *digitp++ - '0'); + has_precision = 1; + } + } + + /* Allocate a temporary buffer of sufficient size. */ + if (type == TYPE_LONGDOUBLE) + tmp_length = + (unsigned int) ((LDBL_DIG + 1) + * 0.831 /* decimal -> hexadecimal */ + ) + + 1; /* turn floor into ceil */ + else + tmp_length = + (unsigned int) ((DBL_DIG + 1) + * 0.831 /* decimal -> hexadecimal */ + ) + + 1; /* turn floor into ceil */ + if (tmp_length < precision) + tmp_length = precision; + /* Account for sign, decimal point etc. */ + tmp_length = xsum (tmp_length, 12); + + if (tmp_length < width) + tmp_length = width; + + tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */ + + if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T)) + tmp = tmpbuf; + else + { + size_t tmp_memsize = xtimes (tmp_length, sizeof (DCHAR_T)); + + if (size_overflow_p (tmp_memsize)) + /* Overflow, would lead to out of memory. */ + goto out_of_memory; + tmp = (DCHAR_T *) malloc (tmp_memsize); + if (tmp == NULL) + /* Out of memory. */ + goto out_of_memory; + } + + pad_ptr = NULL; + p = tmp; + if (type == TYPE_LONGDOUBLE) + { +# if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE + long double arg = a.arg[dp->arg_index].a.a_longdouble; + + if (isnanl (arg)) + { + if (dp->conversion == 'A') + { + *p++ = 'N'; *p++ = 'A'; *p++ = 'N'; + } + else + { + *p++ = 'n'; *p++ = 'a'; *p++ = 'n'; + } + } + else + { + int sign = 0; + DECL_LONG_DOUBLE_ROUNDING + + BEGIN_LONG_DOUBLE_ROUNDING (); + + if (signbit (arg)) /* arg < 0.0L or negative zero */ + { + sign = -1; + arg = -arg; + } + + if (sign < 0) + *p++ = '-'; + else if (flags & FLAG_SHOWSIGN) + *p++ = '+'; + else if (flags & FLAG_SPACE) + *p++ = ' '; + + if (arg > 0.0L && arg + arg == arg) + { + if (dp->conversion == 'A') + { + *p++ = 'I'; *p++ = 'N'; *p++ = 'F'; + } + else + { + *p++ = 'i'; *p++ = 'n'; *p++ = 'f'; + } + } + else + { + int exponent; + long double mantissa; + + if (arg > 0.0L) + mantissa = printf_frexpl (arg, &exponent); + else + { + exponent = 0; + mantissa = 0.0L; + } + + if (has_precision + && precision < (unsigned int) ((LDBL_DIG + 1) * 0.831) + 1) + { + /* Round the mantissa. */ + long double tail = mantissa; + size_t q; + + for (q = precision; ; q--) + { + int digit = (int) tail; + tail -= digit; + if (q == 0) + { + if (digit & 1 ? tail >= 0.5L : tail > 0.5L) + tail = 1 - tail; + else + tail = - tail; + break; + } + tail *= 16.0L; + } + if (tail != 0.0L) + for (q = precision; q > 0; q--) + tail *= 0.0625L; + mantissa += tail; + } + + *p++ = '0'; + *p++ = dp->conversion - 'A' + 'X'; + pad_ptr = p; + { + int digit; + + digit = (int) mantissa; + mantissa -= digit; + *p++ = '0' + digit; + if ((flags & FLAG_ALT) + || mantissa > 0.0L || precision > 0) + { + *p++ = decimal_point_char (); + /* This loop terminates because we assume + that FLT_RADIX is a power of 2. */ + while (mantissa > 0.0L) + { + mantissa *= 16.0L; + digit = (int) mantissa; + mantissa -= digit; + *p++ = digit + + (digit < 10 + ? '0' + : dp->conversion - 10); + if (precision > 0) + precision--; + } + while (precision > 0) + { + *p++ = '0'; + precision--; + } + } + } + *p++ = dp->conversion - 'A' + 'P'; +# if WIDE_CHAR_VERSION + { + static const wchar_t decimal_format[] = + { '%', '+', 'd', '\0' }; + SNPRINTF (p, 6 + 1, decimal_format, exponent); + } + while (*p != '\0') + p++; +# else + if (sizeof (DCHAR_T) == 1) + { + sprintf ((char *) p, "%+d", exponent); + while (*p != '\0') + p++; + } + else + { + char expbuf[6 + 1]; + const char *ep; + sprintf (expbuf, "%+d", exponent); + for (ep = expbuf; (*p = *ep) != '\0'; ep++) + p++; + } +# endif + } + + END_LONG_DOUBLE_ROUNDING (); + } +# else + abort (); +# endif + } + else + { +# if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE + double arg = a.arg[dp->arg_index].a.a_double; + + if (isnand (arg)) + { + if (dp->conversion == 'A') + { + *p++ = 'N'; *p++ = 'A'; *p++ = 'N'; + } + else + { + *p++ = 'n'; *p++ = 'a'; *p++ = 'n'; + } + } + else + { + int sign = 0; + + if (signbit (arg)) /* arg < 0.0 or negative zero */ + { + sign = -1; + arg = -arg; + } + + if (sign < 0) + *p++ = '-'; + else if (flags & FLAG_SHOWSIGN) + *p++ = '+'; + else if (flags & FLAG_SPACE) + *p++ = ' '; + + if (arg > 0.0 && arg + arg == arg) + { + if (dp->conversion == 'A') + { + *p++ = 'I'; *p++ = 'N'; *p++ = 'F'; + } + else + { + *p++ = 'i'; *p++ = 'n'; *p++ = 'f'; + } + } + else + { + int exponent; + double mantissa; + + if (arg > 0.0) + mantissa = printf_frexp (arg, &exponent); + else + { + exponent = 0; + mantissa = 0.0; + } + + if (has_precision + && precision < (unsigned int) ((DBL_DIG + 1) * 0.831) + 1) + { + /* Round the mantissa. */ + double tail = mantissa; + size_t q; + + for (q = precision; ; q--) + { + int digit = (int) tail; + tail -= digit; + if (q == 0) + { + if (digit & 1 ? tail >= 0.5 : tail > 0.5) + tail = 1 - tail; + else + tail = - tail; + break; + } + tail *= 16.0; + } + if (tail != 0.0) + for (q = precision; q > 0; q--) + tail *= 0.0625; + mantissa += tail; + } + + *p++ = '0'; + *p++ = dp->conversion - 'A' + 'X'; + pad_ptr = p; + { + int digit; + + digit = (int) mantissa; + mantissa -= digit; + *p++ = '0' + digit; + if ((flags & FLAG_ALT) + || mantissa > 0.0 || precision > 0) + { + *p++ = decimal_point_char (); + /* This loop terminates because we assume + that FLT_RADIX is a power of 2. */ + while (mantissa > 0.0) + { + mantissa *= 16.0; + digit = (int) mantissa; + mantissa -= digit; + *p++ = digit + + (digit < 10 + ? '0' + : dp->conversion - 10); + if (precision > 0) + precision--; + } + while (precision > 0) + { + *p++ = '0'; + precision--; + } + } + } + *p++ = dp->conversion - 'A' + 'P'; +# if WIDE_CHAR_VERSION + { + static const wchar_t decimal_format[] = + { '%', '+', 'd', '\0' }; + SNPRINTF (p, 6 + 1, decimal_format, exponent); + } + while (*p != '\0') + p++; +# else + if (sizeof (DCHAR_T) == 1) + { + sprintf ((char *) p, "%+d", exponent); + while (*p != '\0') + p++; + } + else + { + char expbuf[6 + 1]; + const char *ep; + sprintf (expbuf, "%+d", exponent); + for (ep = expbuf; (*p = *ep) != '\0'; ep++) + p++; + } +# endif + } + } +# else + abort (); +# endif + } + /* The generated string now extends from tmp to p, with the + zero padding insertion point being at pad_ptr. */ + if (has_width && p - tmp < width) + { + size_t pad = width - (p - tmp); + DCHAR_T *end = p + pad; + + if (flags & FLAG_LEFT) + { + /* Pad with spaces on the right. */ + for (; pad > 0; pad--) + *p++ = ' '; + } + else if ((flags & FLAG_ZERO) && pad_ptr != NULL) + { + /* Pad with zeroes. */ + DCHAR_T *q = end; + + while (p > pad_ptr) + *--q = *--p; + for (; pad > 0; pad--) + *p++ = '0'; + } + else + { + /* Pad with spaces on the left. */ + DCHAR_T *q = end; + + while (p > tmp) + *--q = *--p; + for (; pad > 0; pad--) + *p++ = ' '; + } + + p = end; + } + + { + size_t count = p - tmp; + + if (count >= tmp_length) + /* tmp_length was incorrectly calculated - fix the + code above! */ + abort (); + + /* Make room for the result. */ + if (count >= allocated - length) + { + size_t n = xsum (length, count); + + ENSURE_ALLOCATION (n); + } + + /* Append the result. */ + memcpy (result + length, tmp, count * sizeof (DCHAR_T)); + if (tmp != tmpbuf) + free (tmp); + length += count; + } + } +#endif +#if (NEED_PRINTF_INFINITE_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL + else if ((dp->conversion == 'f' || dp->conversion == 'F' + || dp->conversion == 'e' || dp->conversion == 'E' + || dp->conversion == 'g' || dp->conversion == 'G' + || dp->conversion == 'a' || dp->conversion == 'A') + && (0 +# if NEED_PRINTF_DOUBLE + || a.arg[dp->arg_index].type == TYPE_DOUBLE +# elif NEED_PRINTF_INFINITE_DOUBLE + || (a.arg[dp->arg_index].type == TYPE_DOUBLE + /* The systems (mingw) which produce wrong output + for Inf, -Inf, and NaN also do so for -0.0. + Therefore we treat this case here as well. */ + && is_infinite_or_zero (a.arg[dp->arg_index].a.a_double)) +# endif +# if NEED_PRINTF_LONG_DOUBLE + || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE +# elif NEED_PRINTF_INFINITE_LONG_DOUBLE + || (a.arg[dp->arg_index].type == TYPE_LONGDOUBLE + /* Some systems produce wrong output for Inf, + -Inf, and NaN. Some systems in this category + (IRIX 5.3) also do so for -0.0. Therefore we + treat this case here as well. */ + && is_infinite_or_zerol (a.arg[dp->arg_index].a.a_longdouble)) +# endif + )) + { +# if (NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE) + arg_type type = a.arg[dp->arg_index].type; +# endif + int flags = dp->flags; + int has_width; + size_t width; + int has_precision; + size_t precision; + size_t tmp_length; + DCHAR_T tmpbuf[700]; + DCHAR_T *tmp; + DCHAR_T *pad_ptr; + DCHAR_T *p; + + has_width = 0; + width = 0; + if (dp->width_start != dp->width_end) + { + if (dp->width_arg_index != ARG_NONE) + { + int arg; + + if (!(a.arg[dp->width_arg_index].type == TYPE_INT)) + abort (); + arg = a.arg[dp->width_arg_index].a.a_int; + if (arg < 0) + { + /* "A negative field width is taken as a '-' flag + followed by a positive field width." */ + flags |= FLAG_LEFT; + width = (unsigned int) (-arg); + } + else + width = arg; + } + else + { + const FCHAR_T *digitp = dp->width_start; + + do + width = xsum (xtimes (width, 10), *digitp++ - '0'); + while (digitp != dp->width_end); + } + has_width = 1; + } + + has_precision = 0; + precision = 0; + if (dp->precision_start != dp->precision_end) + { + if (dp->precision_arg_index != ARG_NONE) + { + int arg; + + if (!(a.arg[dp->precision_arg_index].type == TYPE_INT)) + abort (); + arg = a.arg[dp->precision_arg_index].a.a_int; + /* "A negative precision is taken as if the precision + were omitted." */ + if (arg >= 0) + { + precision = arg; + has_precision = 1; + } + } + else + { + const FCHAR_T *digitp = dp->precision_start + 1; + + precision = 0; + while (digitp != dp->precision_end) + precision = xsum (xtimes (precision, 10), *digitp++ - '0'); + has_precision = 1; + } + } + + /* POSIX specifies the default precision to be 6 for %f, %F, + %e, %E, but not for %g, %G. Implementations appear to use + the same default precision also for %g, %G. But for %a, %A, + the default precision is 0. */ + if (!has_precision) + if (!(dp->conversion == 'a' || dp->conversion == 'A')) + precision = 6; + + /* Allocate a temporary buffer of sufficient size. */ +# if NEED_PRINTF_DOUBLE && NEED_PRINTF_LONG_DOUBLE + tmp_length = (type == TYPE_LONGDOUBLE ? LDBL_DIG + 1 : DBL_DIG + 1); +# elif NEED_PRINTF_INFINITE_DOUBLE && NEED_PRINTF_LONG_DOUBLE + tmp_length = (type == TYPE_LONGDOUBLE ? LDBL_DIG + 1 : 0); +# elif NEED_PRINTF_LONG_DOUBLE + tmp_length = LDBL_DIG + 1; +# elif NEED_PRINTF_DOUBLE + tmp_length = DBL_DIG + 1; +# else + tmp_length = 0; +# endif + if (tmp_length < precision) + tmp_length = precision; +# if NEED_PRINTF_LONG_DOUBLE +# if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE + if (type == TYPE_LONGDOUBLE) +# endif + if (dp->conversion == 'f' || dp->conversion == 'F') + { + long double arg = a.arg[dp->arg_index].a.a_longdouble; + if (!(isnanl (arg) || arg + arg == arg)) + { + /* arg is finite and nonzero. */ + int exponent = floorlog10l (arg < 0 ? -arg : arg); + if (exponent >= 0 && tmp_length < exponent + precision) + tmp_length = exponent + precision; + } + } +# endif +# if NEED_PRINTF_DOUBLE +# if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE + if (type == TYPE_DOUBLE) +# endif + if (dp->conversion == 'f' || dp->conversion == 'F') + { + double arg = a.arg[dp->arg_index].a.a_double; + if (!(isnand (arg) || arg + arg == arg)) + { + /* arg is finite and nonzero. */ + int exponent = floorlog10 (arg < 0 ? -arg : arg); + if (exponent >= 0 && tmp_length < exponent + precision) + tmp_length = exponent + precision; + } + } +# endif + /* Account for sign, decimal point etc. */ + tmp_length = xsum (tmp_length, 12); + + if (tmp_length < width) + tmp_length = width; + + tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */ + + if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T)) + tmp = tmpbuf; + else + { + size_t tmp_memsize = xtimes (tmp_length, sizeof (DCHAR_T)); + + if (size_overflow_p (tmp_memsize)) + /* Overflow, would lead to out of memory. */ + goto out_of_memory; + tmp = (DCHAR_T *) malloc (tmp_memsize); + if (tmp == NULL) + /* Out of memory. */ + goto out_of_memory; + } + + pad_ptr = NULL; + p = tmp; + +# if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE +# if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE + if (type == TYPE_LONGDOUBLE) +# endif + { + long double arg = a.arg[dp->arg_index].a.a_longdouble; + + if (isnanl (arg)) + { + if (dp->conversion >= 'A' && dp->conversion <= 'Z') + { + *p++ = 'N'; *p++ = 'A'; *p++ = 'N'; + } + else + { + *p++ = 'n'; *p++ = 'a'; *p++ = 'n'; + } + } + else + { + int sign = 0; + DECL_LONG_DOUBLE_ROUNDING + + BEGIN_LONG_DOUBLE_ROUNDING (); + + if (signbit (arg)) /* arg < 0.0L or negative zero */ + { + sign = -1; + arg = -arg; + } + + if (sign < 0) + *p++ = '-'; + else if (flags & FLAG_SHOWSIGN) + *p++ = '+'; + else if (flags & FLAG_SPACE) + *p++ = ' '; + + if (arg > 0.0L && arg + arg == arg) + { + if (dp->conversion >= 'A' && dp->conversion <= 'Z') + { + *p++ = 'I'; *p++ = 'N'; *p++ = 'F'; + } + else + { + *p++ = 'i'; *p++ = 'n'; *p++ = 'f'; + } + } + else + { +# if NEED_PRINTF_LONG_DOUBLE + pad_ptr = p; + + if (dp->conversion == 'f' || dp->conversion == 'F') + { + char *digits; + size_t ndigits; + + digits = + scale10_round_decimal_long_double (arg, precision); + if (digits == NULL) + { + END_LONG_DOUBLE_ROUNDING (); + goto out_of_memory; + } + ndigits = strlen (digits); + + if (ndigits > precision) + do + { + --ndigits; + *p++ = digits[ndigits]; + } + while (ndigits > precision); + else + *p++ = '0'; + /* Here ndigits <= precision. */ + if ((flags & FLAG_ALT) || precision > 0) + { + *p++ = decimal_point_char (); + for (; precision > ndigits; precision--) + *p++ = '0'; + while (ndigits > 0) + { + --ndigits; + *p++ = digits[ndigits]; + } + } + + free (digits); + } + else if (dp->conversion == 'e' || dp->conversion == 'E') + { + int exponent; + + if (arg == 0.0L) + { + exponent = 0; + *p++ = '0'; + if ((flags & FLAG_ALT) || precision > 0) + { + *p++ = decimal_point_char (); + for (; precision > 0; precision--) + *p++ = '0'; + } + } + else + { + /* arg > 0.0L. */ + int adjusted; + char *digits; + size_t ndigits; + + exponent = floorlog10l (arg); + adjusted = 0; + for (;;) + { + digits = + scale10_round_decimal_long_double (arg, + (int)precision - exponent); + if (digits == NULL) + { + END_LONG_DOUBLE_ROUNDING (); + goto out_of_memory; + } + ndigits = strlen (digits); + + if (ndigits == precision + 1) + break; + if (ndigits < precision + || ndigits > precision + 2) + /* The exponent was not guessed + precisely enough. */ + abort (); + if (adjusted) + /* None of two values of exponent is + the right one. Prevent an endless + loop. */ + abort (); + free (digits); + if (ndigits == precision) + exponent -= 1; + else + exponent += 1; + adjusted = 1; + } + /* Here ndigits = precision+1. */ + if (is_borderline (digits, precision)) + { + /* Maybe the exponent guess was too high + and a smaller exponent can be reached + by turning a 10...0 into 9...9x. */ + char *digits2 = + scale10_round_decimal_long_double (arg, + (int)precision - exponent + 1); + if (digits2 == NULL) + { + free (digits); + END_LONG_DOUBLE_ROUNDING (); + goto out_of_memory; + } + if (strlen (digits2) == precision + 1) + { + free (digits); + digits = digits2; + exponent -= 1; + } + else + free (digits2); + } + /* Here ndigits = precision+1. */ + + *p++ = digits[--ndigits]; + if ((flags & FLAG_ALT) || precision > 0) + { + *p++ = decimal_point_char (); + while (ndigits > 0) + { + --ndigits; + *p++ = digits[ndigits]; + } + } + + free (digits); + } + + *p++ = dp->conversion; /* 'e' or 'E' */ +# if WIDE_CHAR_VERSION + { + static const wchar_t decimal_format[] = + { '%', '+', '.', '2', 'd', '\0' }; + SNPRINTF (p, 6 + 1, decimal_format, exponent); + } + while (*p != '\0') + p++; +# else + if (sizeof (DCHAR_T) == 1) + { + sprintf ((char *) p, "%+.2d", exponent); + while (*p != '\0') + p++; + } + else + { + char expbuf[6 + 1]; + const char *ep; + sprintf (expbuf, "%+.2d", exponent); + for (ep = expbuf; (*p = *ep) != '\0'; ep++) + p++; + } +# endif + } + else if (dp->conversion == 'g' || dp->conversion == 'G') + { + if (precision == 0) + precision = 1; + /* precision >= 1. */ + + if (arg == 0.0L) + /* The exponent is 0, >= -4, < precision. + Use fixed-point notation. */ + { + size_t ndigits = precision; + /* Number of trailing zeroes that have to be + dropped. */ + size_t nzeroes = + (flags & FLAG_ALT ? 0 : precision - 1); + + --ndigits; + *p++ = '0'; + if ((flags & FLAG_ALT) || ndigits > nzeroes) + { + *p++ = decimal_point_char (); + while (ndigits > nzeroes) + { + --ndigits; + *p++ = '0'; + } + } + } + else + { + /* arg > 0.0L. */ + int exponent; + int adjusted; + char *digits; + size_t ndigits; + size_t nzeroes; + + exponent = floorlog10l (arg); + adjusted = 0; + for (;;) + { + digits = + scale10_round_decimal_long_double (arg, + (int)(precision - 1) - exponent); + if (digits == NULL) + { + END_LONG_DOUBLE_ROUNDING (); + goto out_of_memory; + } + ndigits = strlen (digits); + + if (ndigits == precision) + break; + if (ndigits < precision - 1 + || ndigits > precision + 1) + /* The exponent was not guessed + precisely enough. */ + abort (); + if (adjusted) + /* None of two values of exponent is + the right one. Prevent an endless + loop. */ + abort (); + free (digits); + if (ndigits < precision) + exponent -= 1; + else + exponent += 1; + adjusted = 1; + } + /* Here ndigits = precision. */ + if (is_borderline (digits, precision - 1)) + { + /* Maybe the exponent guess was too high + and a smaller exponent can be reached + by turning a 10...0 into 9...9x. */ + char *digits2 = + scale10_round_decimal_long_double (arg, + (int)(precision - 1) - exponent + 1); + if (digits2 == NULL) + { + free (digits); + END_LONG_DOUBLE_ROUNDING (); + goto out_of_memory; + } + if (strlen (digits2) == precision) + { + free (digits); + digits = digits2; + exponent -= 1; + } + else + free (digits2); + } + /* Here ndigits = precision. */ + + /* Determine the number of trailing zeroes + that have to be dropped. */ + nzeroes = 0; + if ((flags & FLAG_ALT) == 0) + while (nzeroes < ndigits + && digits[nzeroes] == '0') + nzeroes++; + + /* The exponent is now determined. */ + if (exponent >= -4 + && exponent < (long)precision) + { + /* Fixed-point notation: + max(exponent,0)+1 digits, then the + decimal point, then the remaining + digits without trailing zeroes. */ + if (exponent >= 0) + { + size_t count = exponent + 1; + /* Note: count <= precision = ndigits. */ + for (; count > 0; count--) + *p++ = digits[--ndigits]; + if ((flags & FLAG_ALT) || ndigits > nzeroes) + { + *p++ = decimal_point_char (); + while (ndigits > nzeroes) + { + --ndigits; + *p++ = digits[ndigits]; + } + } + } + else + { + size_t count = -exponent - 1; + *p++ = '0'; + *p++ = decimal_point_char (); + for (; count > 0; count--) + *p++ = '0'; + while (ndigits > nzeroes) + { + --ndigits; + *p++ = digits[ndigits]; + } + } + } + else + { + /* Exponential notation. */ + *p++ = digits[--ndigits]; + if ((flags & FLAG_ALT) || ndigits > nzeroes) + { + *p++ = decimal_point_char (); + while (ndigits > nzeroes) + { + --ndigits; + *p++ = digits[ndigits]; + } + } + *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */ +# if WIDE_CHAR_VERSION + { + static const wchar_t decimal_format[] = + { '%', '+', '.', '2', 'd', '\0' }; + SNPRINTF (p, 6 + 1, decimal_format, exponent); + } + while (*p != '\0') + p++; +# else + if (sizeof (DCHAR_T) == 1) + { + sprintf ((char *) p, "%+.2d", exponent); + while (*p != '\0') + p++; + } + else + { + char expbuf[6 + 1]; + const char *ep; + sprintf (expbuf, "%+.2d", exponent); + for (ep = expbuf; (*p = *ep) != '\0'; ep++) + p++; + } +# endif + } + + free (digits); + } + } + else + abort (); +# else + /* arg is finite. */ + if (!(arg == 0.0L)) + abort (); + + pad_ptr = p; + + if (dp->conversion == 'f' || dp->conversion == 'F') + { + *p++ = '0'; + if ((flags & FLAG_ALT) || precision > 0) + { + *p++ = decimal_point_char (); + for (; precision > 0; precision--) + *p++ = '0'; + } + } + else if (dp->conversion == 'e' || dp->conversion == 'E') + { + *p++ = '0'; + if ((flags & FLAG_ALT) || precision > 0) + { + *p++ = decimal_point_char (); + for (; precision > 0; precision--) + *p++ = '0'; + } + *p++ = dp->conversion; /* 'e' or 'E' */ + *p++ = '+'; + *p++ = '0'; + *p++ = '0'; + } + else if (dp->conversion == 'g' || dp->conversion == 'G') + { + *p++ = '0'; + if (flags & FLAG_ALT) + { + size_t ndigits = + (precision > 0 ? precision - 1 : 0); + *p++ = decimal_point_char (); + for (; ndigits > 0; --ndigits) + *p++ = '0'; + } + } + else if (dp->conversion == 'a' || dp->conversion == 'A') + { + *p++ = '0'; + *p++ = dp->conversion - 'A' + 'X'; + pad_ptr = p; + *p++ = '0'; + if ((flags & FLAG_ALT) || precision > 0) + { + *p++ = decimal_point_char (); + for (; precision > 0; precision--) + *p++ = '0'; + } + *p++ = dp->conversion - 'A' + 'P'; + *p++ = '+'; + *p++ = '0'; + } + else + abort (); +# endif + } + + END_LONG_DOUBLE_ROUNDING (); + } + } +# if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE + else +# endif +# endif +# if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE + { + double arg = a.arg[dp->arg_index].a.a_double; + + if (isnand (arg)) + { + if (dp->conversion >= 'A' && dp->conversion <= 'Z') + { + *p++ = 'N'; *p++ = 'A'; *p++ = 'N'; + } + else + { + *p++ = 'n'; *p++ = 'a'; *p++ = 'n'; + } + } + else + { + int sign = 0; + + if (signbit (arg)) /* arg < 0.0 or negative zero */ + { + sign = -1; + arg = -arg; + } + + if (sign < 0) + *p++ = '-'; + else if (flags & FLAG_SHOWSIGN) + *p++ = '+'; + else if (flags & FLAG_SPACE) + *p++ = ' '; + + if (arg > 0.0 && arg + arg == arg) + { + if (dp->conversion >= 'A' && dp->conversion <= 'Z') + { + *p++ = 'I'; *p++ = 'N'; *p++ = 'F'; + } + else + { + *p++ = 'i'; *p++ = 'n'; *p++ = 'f'; + } + } + else + { +# if NEED_PRINTF_DOUBLE + pad_ptr = p; + + if (dp->conversion == 'f' || dp->conversion == 'F') + { + char *digits; + size_t ndigits; + + digits = + scale10_round_decimal_double (arg, precision); + if (digits == NULL) + goto out_of_memory; + ndigits = strlen (digits); + + if (ndigits > precision) + do + { + --ndigits; + *p++ = digits[ndigits]; + } + while (ndigits > precision); + else + *p++ = '0'; + /* Here ndigits <= precision. */ + if ((flags & FLAG_ALT) || precision > 0) + { + *p++ = decimal_point_char (); + for (; precision > ndigits; precision--) + *p++ = '0'; + while (ndigits > 0) + { + --ndigits; + *p++ = digits[ndigits]; + } + } + + free (digits); + } + else if (dp->conversion == 'e' || dp->conversion == 'E') + { + int exponent; + + if (arg == 0.0) + { + exponent = 0; + *p++ = '0'; + if ((flags & FLAG_ALT) || precision > 0) + { + *p++ = decimal_point_char (); + for (; precision > 0; precision--) + *p++ = '0'; + } + } + else + { + /* arg > 0.0. */ + int adjusted; + char *digits; + size_t ndigits; + + exponent = floorlog10 (arg); + adjusted = 0; + for (;;) + { + digits = + scale10_round_decimal_double (arg, + (int)precision - exponent); + if (digits == NULL) + goto out_of_memory; + ndigits = strlen (digits); + + if (ndigits == precision + 1) + break; + if (ndigits < precision + || ndigits > precision + 2) + /* The exponent was not guessed + precisely enough. */ + abort (); + if (adjusted) + /* None of two values of exponent is + the right one. Prevent an endless + loop. */ + abort (); + free (digits); + if (ndigits == precision) + exponent -= 1; + else + exponent += 1; + adjusted = 1; + } + /* Here ndigits = precision+1. */ + if (is_borderline (digits, precision)) + { + /* Maybe the exponent guess was too high + and a smaller exponent can be reached + by turning a 10...0 into 9...9x. */ + char *digits2 = + scale10_round_decimal_double (arg, + (int)precision - exponent + 1); + if (digits2 == NULL) + { + free (digits); + goto out_of_memory; + } + if (strlen (digits2) == precision + 1) + { + free (digits); + digits = digits2; + exponent -= 1; + } + else + free (digits2); + } + /* Here ndigits = precision+1. */ + + *p++ = digits[--ndigits]; + if ((flags & FLAG_ALT) || precision > 0) + { + *p++ = decimal_point_char (); + while (ndigits > 0) + { + --ndigits; + *p++ = digits[ndigits]; + } + } + + free (digits); + } + + *p++ = dp->conversion; /* 'e' or 'E' */ +# if WIDE_CHAR_VERSION + { + static const wchar_t decimal_format[] = + /* Produce the same number of exponent digits + as the native printf implementation. */ +# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ + { '%', '+', '.', '3', 'd', '\0' }; +# else + { '%', '+', '.', '2', 'd', '\0' }; +# endif + SNPRINTF (p, 6 + 1, decimal_format, exponent); + } + while (*p != '\0') + p++; +# else + { + static const char decimal_format[] = + /* Produce the same number of exponent digits + as the native printf implementation. */ +# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ + "%+.3d"; +# else + "%+.2d"; +# endif + if (sizeof (DCHAR_T) == 1) + { + sprintf ((char *) p, decimal_format, exponent); + while (*p != '\0') + p++; + } + else + { + char expbuf[6 + 1]; + const char *ep; + sprintf (expbuf, decimal_format, exponent); + for (ep = expbuf; (*p = *ep) != '\0'; ep++) + p++; + } + } +# endif + } + else if (dp->conversion == 'g' || dp->conversion == 'G') + { + if (precision == 0) + precision = 1; + /* precision >= 1. */ + + if (arg == 0.0) + /* The exponent is 0, >= -4, < precision. + Use fixed-point notation. */ + { + size_t ndigits = precision; + /* Number of trailing zeroes that have to be + dropped. */ + size_t nzeroes = + (flags & FLAG_ALT ? 0 : precision - 1); + + --ndigits; + *p++ = '0'; + if ((flags & FLAG_ALT) || ndigits > nzeroes) + { + *p++ = decimal_point_char (); + while (ndigits > nzeroes) + { + --ndigits; + *p++ = '0'; + } + } + } + else + { + /* arg > 0.0. */ + int exponent; + int adjusted; + char *digits; + size_t ndigits; + size_t nzeroes; + + exponent = floorlog10 (arg); + adjusted = 0; + for (;;) + { + digits = + scale10_round_decimal_double (arg, + (int)(precision - 1) - exponent); + if (digits == NULL) + goto out_of_memory; + ndigits = strlen (digits); + + if (ndigits == precision) + break; + if (ndigits < precision - 1 + || ndigits > precision + 1) + /* The exponent was not guessed + precisely enough. */ + abort (); + if (adjusted) + /* None of two values of exponent is + the right one. Prevent an endless + loop. */ + abort (); + free (digits); + if (ndigits < precision) + exponent -= 1; + else + exponent += 1; + adjusted = 1; + } + /* Here ndigits = precision. */ + if (is_borderline (digits, precision - 1)) + { + /* Maybe the exponent guess was too high + and a smaller exponent can be reached + by turning a 10...0 into 9...9x. */ + char *digits2 = + scale10_round_decimal_double (arg, + (int)(precision - 1) - exponent + 1); + if (digits2 == NULL) + { + free (digits); + goto out_of_memory; + } + if (strlen (digits2) == precision) + { + free (digits); + digits = digits2; + exponent -= 1; + } + else + free (digits2); + } + /* Here ndigits = precision. */ + + /* Determine the number of trailing zeroes + that have to be dropped. */ + nzeroes = 0; + if ((flags & FLAG_ALT) == 0) + while (nzeroes < ndigits + && digits[nzeroes] == '0') + nzeroes++; + + /* The exponent is now determined. */ + if (exponent >= -4 + && exponent < (long)precision) + { + /* Fixed-point notation: + max(exponent,0)+1 digits, then the + decimal point, then the remaining + digits without trailing zeroes. */ + if (exponent >= 0) + { + size_t count = exponent + 1; + /* Note: count <= precision = ndigits. */ + for (; count > 0; count--) + *p++ = digits[--ndigits]; + if ((flags & FLAG_ALT) || ndigits > nzeroes) + { + *p++ = decimal_point_char (); + while (ndigits > nzeroes) + { + --ndigits; + *p++ = digits[ndigits]; + } + } + } + else + { + size_t count = -exponent - 1; + *p++ = '0'; + *p++ = decimal_point_char (); + for (; count > 0; count--) + *p++ = '0'; + while (ndigits > nzeroes) + { + --ndigits; + *p++ = digits[ndigits]; + } + } + } + else + { + /* Exponential notation. */ + *p++ = digits[--ndigits]; + if ((flags & FLAG_ALT) || ndigits > nzeroes) + { + *p++ = decimal_point_char (); + while (ndigits > nzeroes) + { + --ndigits; + *p++ = digits[ndigits]; + } + } + *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */ +# if WIDE_CHAR_VERSION + { + static const wchar_t decimal_format[] = + /* Produce the same number of exponent digits + as the native printf implementation. */ +# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ + { '%', '+', '.', '3', 'd', '\0' }; +# else + { '%', '+', '.', '2', 'd', '\0' }; +# endif + SNPRINTF (p, 6 + 1, decimal_format, exponent); + } + while (*p != '\0') + p++; +# else + { + static const char decimal_format[] = + /* Produce the same number of exponent digits + as the native printf implementation. */ +# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ + "%+.3d"; +# else + "%+.2d"; +# endif + if (sizeof (DCHAR_T) == 1) + { + sprintf ((char *) p, decimal_format, exponent); + while (*p != '\0') + p++; + } + else + { + char expbuf[6 + 1]; + const char *ep; + sprintf (expbuf, decimal_format, exponent); + for (ep = expbuf; (*p = *ep) != '\0'; ep++) + p++; + } + } +# endif + } + + free (digits); + } + } + else + abort (); +# else + /* arg is finite. */ + if (!(arg == 0.0)) + abort (); + + pad_ptr = p; + + if (dp->conversion == 'f' || dp->conversion == 'F') + { + *p++ = '0'; + if ((flags & FLAG_ALT) || precision > 0) + { + *p++ = decimal_point_char (); + for (; precision > 0; precision--) + *p++ = '0'; + } + } + else if (dp->conversion == 'e' || dp->conversion == 'E') + { + *p++ = '0'; + if ((flags & FLAG_ALT) || precision > 0) + { + *p++ = decimal_point_char (); + for (; precision > 0; precision--) + *p++ = '0'; + } + *p++ = dp->conversion; /* 'e' or 'E' */ + *p++ = '+'; + /* Produce the same number of exponent digits as + the native printf implementation. */ +# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ + *p++ = '0'; +# endif + *p++ = '0'; + *p++ = '0'; + } + else if (dp->conversion == 'g' || dp->conversion == 'G') + { + *p++ = '0'; + if (flags & FLAG_ALT) + { + size_t ndigits = + (precision > 0 ? precision - 1 : 0); + *p++ = decimal_point_char (); + for (; ndigits > 0; --ndigits) + *p++ = '0'; + } + } + else + abort (); +# endif + } + } + } +# endif + + /* The generated string now extends from tmp to p, with the + zero padding insertion point being at pad_ptr. */ + if (has_width && p - tmp < width) + { + size_t pad = width - (p - tmp); + DCHAR_T *end = p + pad; + + if (flags & FLAG_LEFT) + { + /* Pad with spaces on the right. */ + for (; pad > 0; pad--) + *p++ = ' '; + } + else if ((flags & FLAG_ZERO) && pad_ptr != NULL) + { + /* Pad with zeroes. */ + DCHAR_T *q = end; + + while (p > pad_ptr) + *--q = *--p; + for (; pad > 0; pad--) + *p++ = '0'; + } + else + { + /* Pad with spaces on the left. */ + DCHAR_T *q = end; + + while (p > tmp) + *--q = *--p; + for (; pad > 0; pad--) + *p++ = ' '; + } + + p = end; + } + + { + size_t count = p - tmp; + + if (count >= tmp_length) + /* tmp_length was incorrectly calculated - fix the + code above! */ + abort (); + + /* Make room for the result. */ + if (count >= allocated - length) + { + size_t n = xsum (length, count); + + ENSURE_ALLOCATION (n); + } + + /* Append the result. */ + memcpy (result + length, tmp, count * sizeof (DCHAR_T)); + if (tmp != tmpbuf) + free (tmp); + length += count; + } + } +#endif + else + { + arg_type type = a.arg[dp->arg_index].type; + int flags = dp->flags; +#if !USE_SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION + int has_width; + size_t width; +#endif +#if !USE_SNPRINTF || NEED_PRINTF_UNBOUNDED_PRECISION + int has_precision; + size_t precision; +#endif +#if NEED_PRINTF_UNBOUNDED_PRECISION + int prec_ourselves; +#else +# define prec_ourselves 0 +#endif +#if NEED_PRINTF_FLAG_LEFTADJUST +# define pad_ourselves 1 +#elif !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION + int pad_ourselves; +#else +# define pad_ourselves 0 +#endif + TCHAR_T *fbp; + unsigned int prefix_count; + int prefixes[2] IF_LINT (= { 0 }); +#if !USE_SNPRINTF + size_t tmp_length; + TCHAR_T tmpbuf[700]; + TCHAR_T *tmp; +#endif + +#if !USE_SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION + has_width = 0; + width = 0; + if (dp->width_start != dp->width_end) + { + if (dp->width_arg_index != ARG_NONE) + { + int arg; + + if (!(a.arg[dp->width_arg_index].type == TYPE_INT)) + abort (); + arg = a.arg[dp->width_arg_index].a.a_int; + if (arg < 0) + { + /* "A negative field width is taken as a '-' flag + followed by a positive field width." */ + flags |= FLAG_LEFT; + width = (unsigned int) (-arg); + } + else + width = arg; + } + else + { + const FCHAR_T *digitp = dp->width_start; + + do + width = xsum (xtimes (width, 10), *digitp++ - '0'); + while (digitp != dp->width_end); + } + has_width = 1; + } +#endif + +#if !USE_SNPRINTF || NEED_PRINTF_UNBOUNDED_PRECISION + has_precision = 0; + precision = 6; + if (dp->precision_start != dp->precision_end) + { + if (dp->precision_arg_index != ARG_NONE) + { + int arg; + + if (!(a.arg[dp->precision_arg_index].type == TYPE_INT)) + abort (); + arg = a.arg[dp->precision_arg_index].a.a_int; + /* "A negative precision is taken as if the precision + were omitted." */ + if (arg >= 0) + { + precision = arg; + has_precision = 1; + } + } + else + { + const FCHAR_T *digitp = dp->precision_start + 1; + + precision = 0; + while (digitp != dp->precision_end) + precision = xsum (xtimes (precision, 10), *digitp++ - '0'); + has_precision = 1; + } + } +#endif + + /* Decide whether to handle the precision ourselves. */ +#if NEED_PRINTF_UNBOUNDED_PRECISION + switch (dp->conversion) + { + case 'd': case 'i': case 'u': + case 'o': + case 'x': case 'X': case 'p': + prec_ourselves = has_precision && (precision > 0); + break; + default: + prec_ourselves = 0; + break; + } +#endif + + /* Decide whether to perform the padding ourselves. */ +#if !NEED_PRINTF_FLAG_LEFTADJUST && (!DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION) + switch (dp->conversion) + { +# if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO + /* If we need conversion from TCHAR_T[] to DCHAR_T[], we need + to perform the padding after this conversion. Functions + with unistdio extensions perform the padding based on + character count rather than element count. */ + case 'c': case 's': +# endif +# if NEED_PRINTF_FLAG_ZERO + case 'f': case 'F': case 'e': case 'E': case 'g': case 'G': + case 'a': case 'A': +# endif + pad_ourselves = 1; + break; + default: + pad_ourselves = prec_ourselves; + break; + } +#endif + +#if !USE_SNPRINTF + /* Allocate a temporary buffer of sufficient size for calling + sprintf. */ + { + switch (dp->conversion) + { + + case 'd': case 'i': case 'u': +# if HAVE_LONG_LONG_INT + if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT) + tmp_length = + (unsigned int) (sizeof (unsigned long long) * CHAR_BIT + * 0.30103 /* binary -> decimal */ + ) + + 1; /* turn floor into ceil */ + else +# endif + if (type == TYPE_LONGINT || type == TYPE_ULONGINT) + tmp_length = + (unsigned int) (sizeof (unsigned long) * CHAR_BIT + * 0.30103 /* binary -> decimal */ + ) + + 1; /* turn floor into ceil */ + else + tmp_length = + (unsigned int) (sizeof (unsigned int) * CHAR_BIT + * 0.30103 /* binary -> decimal */ + ) + + 1; /* turn floor into ceil */ + if (tmp_length < precision) + tmp_length = precision; + /* Multiply by 2, as an estimate for FLAG_GROUP. */ + tmp_length = xsum (tmp_length, tmp_length); + /* Add 1, to account for a leading sign. */ + tmp_length = xsum (tmp_length, 1); + break; + + case 'o': +# if HAVE_LONG_LONG_INT + if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT) + tmp_length = + (unsigned int) (sizeof (unsigned long long) * CHAR_BIT + * 0.333334 /* binary -> octal */ + ) + + 1; /* turn floor into ceil */ + else +# endif + if (type == TYPE_LONGINT || type == TYPE_ULONGINT) + tmp_length = + (unsigned int) (sizeof (unsigned long) * CHAR_BIT + * 0.333334 /* binary -> octal */ + ) + + 1; /* turn floor into ceil */ + else + tmp_length = + (unsigned int) (sizeof (unsigned int) * CHAR_BIT + * 0.333334 /* binary -> octal */ + ) + + 1; /* turn floor into ceil */ + if (tmp_length < precision) + tmp_length = precision; + /* Add 1, to account for a leading sign. */ + tmp_length = xsum (tmp_length, 1); + break; + + case 'x': case 'X': +# if HAVE_LONG_LONG_INT + if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT) + tmp_length = + (unsigned int) (sizeof (unsigned long long) * CHAR_BIT + * 0.25 /* binary -> hexadecimal */ + ) + + 1; /* turn floor into ceil */ + else +# endif + if (type == TYPE_LONGINT || type == TYPE_ULONGINT) + tmp_length = + (unsigned int) (sizeof (unsigned long) * CHAR_BIT + * 0.25 /* binary -> hexadecimal */ + ) + + 1; /* turn floor into ceil */ + else + tmp_length = + (unsigned int) (sizeof (unsigned int) * CHAR_BIT + * 0.25 /* binary -> hexadecimal */ + ) + + 1; /* turn floor into ceil */ + if (tmp_length < precision) + tmp_length = precision; + /* Add 2, to account for a leading sign or alternate form. */ + tmp_length = xsum (tmp_length, 2); + break; + + case 'f': case 'F': + if (type == TYPE_LONGDOUBLE) + tmp_length = + (unsigned int) (LDBL_MAX_EXP + * 0.30103 /* binary -> decimal */ + * 2 /* estimate for FLAG_GROUP */ + ) + + 1 /* turn floor into ceil */ + + 10; /* sign, decimal point etc. */ + else + tmp_length = + (unsigned int) (DBL_MAX_EXP + * 0.30103 /* binary -> decimal */ + * 2 /* estimate for FLAG_GROUP */ + ) + + 1 /* turn floor into ceil */ + + 10; /* sign, decimal point etc. */ + tmp_length = xsum (tmp_length, precision); + break; + + case 'e': case 'E': case 'g': case 'G': + tmp_length = + 12; /* sign, decimal point, exponent etc. */ + tmp_length = xsum (tmp_length, precision); + break; + + case 'a': case 'A': + if (type == TYPE_LONGDOUBLE) + tmp_length = + (unsigned int) (LDBL_DIG + * 0.831 /* decimal -> hexadecimal */ + ) + + 1; /* turn floor into ceil */ + else + tmp_length = + (unsigned int) (DBL_DIG + * 0.831 /* decimal -> hexadecimal */ + ) + + 1; /* turn floor into ceil */ + if (tmp_length < precision) + tmp_length = precision; + /* Account for sign, decimal point etc. */ + tmp_length = xsum (tmp_length, 12); + break; + + case 'c': +# if HAVE_WINT_T && !WIDE_CHAR_VERSION + if (type == TYPE_WIDE_CHAR) + tmp_length = MB_CUR_MAX; + else +# endif + tmp_length = 1; + break; + + case 's': +# if HAVE_WCHAR_T + if (type == TYPE_WIDE_STRING) + { +# if WIDE_CHAR_VERSION + /* ISO C says about %ls in fwprintf: + "If the precision is not specified or is greater + than the size of the array, the array shall + contain a null wide character." + So if there is a precision, we must not use + wcslen. */ + const wchar_t *arg = + a.arg[dp->arg_index].a.a_wide_string; + + if (has_precision) + tmp_length = local_wcsnlen (arg, precision); + else + tmp_length = local_wcslen (arg); +# else + /* ISO C says about %ls in fprintf: + "If a precision is specified, no more than that + many bytes are written (including shift + sequences, if any), and the array shall contain + a null wide character if, to equal the + multibyte character sequence length given by + the precision, the function would need to + access a wide character one past the end of the + array." + So if there is a precision, we must not use + wcslen. */ + /* This case has already been handled above. */ + abort (); +# endif + } + else +# endif + { +# if WIDE_CHAR_VERSION + /* ISO C says about %s in fwprintf: + "If the precision is not specified or is greater + than the size of the converted array, the + converted array shall contain a null wide + character." + So if there is a precision, we must not use + strlen. */ + /* This case has already been handled above. */ + abort (); +# else + /* ISO C says about %s in fprintf: + "If the precision is not specified or greater + than the size of the array, the array shall + contain a null character." + So if there is a precision, we must not use + strlen. */ + const char *arg = a.arg[dp->arg_index].a.a_string; + + if (has_precision) + tmp_length = local_strnlen (arg, precision); + else + tmp_length = strlen (arg); +# endif + } + break; + + case 'p': + tmp_length = + (unsigned int) (sizeof (void *) * CHAR_BIT + * 0.25 /* binary -> hexadecimal */ + ) + + 1 /* turn floor into ceil */ + + 2; /* account for leading 0x */ + break; + + default: + abort (); + } + + if (!pad_ourselves) + { +# if ENABLE_UNISTDIO + /* Padding considers the number of characters, therefore + the number of elements after padding may be + > max (tmp_length, width) + but is certainly + <= tmp_length + width. */ + tmp_length = xsum (tmp_length, width); +# else + /* Padding considers the number of elements, + says POSIX. */ + if (tmp_length < width) + tmp_length = width; +# endif + } + + tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */ + } + + if (tmp_length <= sizeof (tmpbuf) / sizeof (TCHAR_T)) + tmp = tmpbuf; + else + { + size_t tmp_memsize = xtimes (tmp_length, sizeof (TCHAR_T)); + + if (size_overflow_p (tmp_memsize)) + /* Overflow, would lead to out of memory. */ + goto out_of_memory; + tmp = (TCHAR_T *) malloc (tmp_memsize); + if (tmp == NULL) + /* Out of memory. */ + goto out_of_memory; + } +#endif + + /* Construct the format string for calling snprintf or + sprintf. */ + fbp = buf; + *fbp++ = '%'; +#if NEED_PRINTF_FLAG_GROUPING + /* The underlying implementation doesn't support the ' flag. + Produce no grouping characters in this case; this is + acceptable because the grouping is locale dependent. */ +#else + if (flags & FLAG_GROUP) + *fbp++ = '\''; +#endif + if (flags & FLAG_LEFT) + *fbp++ = '-'; + if (flags & FLAG_SHOWSIGN) + *fbp++ = '+'; + if (flags & FLAG_SPACE) + *fbp++ = ' '; + if (flags & FLAG_ALT) + *fbp++ = '#'; + if (!pad_ourselves) + { + if (flags & FLAG_ZERO) + *fbp++ = '0'; + if (dp->width_start != dp->width_end) + { + size_t n = dp->width_end - dp->width_start; + /* The width specification is known to consist only + of standard ASCII characters. */ + if (sizeof (FCHAR_T) == sizeof (TCHAR_T)) + { + memcpy (fbp, dp->width_start, n * sizeof (TCHAR_T)); + fbp += n; + } + else + { + const FCHAR_T *mp = dp->width_start; + do + *fbp++ = (unsigned char) *mp++; + while (--n > 0); + } + } + } + if (!prec_ourselves) + { + if (dp->precision_start != dp->precision_end) + { + size_t n = dp->precision_end - dp->precision_start; + /* The precision specification is known to consist only + of standard ASCII characters. */ + if (sizeof (FCHAR_T) == sizeof (TCHAR_T)) + { + memcpy (fbp, dp->precision_start, n * sizeof (TCHAR_T)); + fbp += n; + } + else + { + const FCHAR_T *mp = dp->precision_start; + do + *fbp++ = (unsigned char) *mp++; + while (--n > 0); + } + } + } + + switch (type) + { +#if HAVE_LONG_LONG_INT + case TYPE_LONGLONGINT: + case TYPE_ULONGLONGINT: +# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ + *fbp++ = 'I'; + *fbp++ = '6'; + *fbp++ = '4'; + break; +# else + *fbp++ = 'l'; + /*FALLTHROUGH*/ +# endif +#endif + case TYPE_LONGINT: + case TYPE_ULONGINT: +#if HAVE_WINT_T + case TYPE_WIDE_CHAR: +#endif +#if HAVE_WCHAR_T + case TYPE_WIDE_STRING: +#endif + *fbp++ = 'l'; + break; + case TYPE_LONGDOUBLE: + *fbp++ = 'L'; + break; + default: + break; + } +#if NEED_PRINTF_DIRECTIVE_F + if (dp->conversion == 'F') + *fbp = 'f'; + else +#endif + *fbp = dp->conversion; +#if USE_SNPRINTF +# if !(__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3) || ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__)) + fbp[1] = '%'; + fbp[2] = 'n'; + fbp[3] = '\0'; +# else + /* On glibc2 systems from glibc >= 2.3 - probably also older + ones - we know that snprintf's returns value conforms to + ISO C 99: the gl_SNPRINTF_DIRECTIVE_N test passes. + Therefore we can avoid using %n in this situation. + On glibc2 systems from 2004-10-18 or newer, the use of %n + in format strings in writable memory may crash the program + (if compiled with _FORTIFY_SOURCE=2), so we should avoid it + in this situation. */ + /* On native Win32 systems (such as mingw), we can avoid using + %n because: + - Although the gl_SNPRINTF_TRUNCATION_C99 test fails, + snprintf does not write more than the specified number + of bytes. (snprintf (buf, 3, "%d %d", 4567, 89) writes + '4', '5', '6' into buf, not '4', '5', '\0'.) + - Although the gl_SNPRINTF_RETVAL_C99 test fails, snprintf + allows us to recognize the case of an insufficient + buffer size: it returns -1 in this case. + On native Win32 systems (such as mingw) where the OS is + Windows Vista, the use of %n in format strings by default + crashes the program. See + and + + So we should avoid %n in this situation. */ + fbp[1] = '\0'; +# endif +#else + fbp[1] = '\0'; +#endif + + /* Construct the arguments for calling snprintf or sprintf. */ + prefix_count = 0; + if (!pad_ourselves && dp->width_arg_index != ARG_NONE) + { + if (!(a.arg[dp->width_arg_index].type == TYPE_INT)) + abort (); + prefixes[prefix_count++] = a.arg[dp->width_arg_index].a.a_int; + } + if (!prec_ourselves && dp->precision_arg_index != ARG_NONE) + { + if (!(a.arg[dp->precision_arg_index].type == TYPE_INT)) + abort (); + prefixes[prefix_count++] = a.arg[dp->precision_arg_index].a.a_int; + } + +#if USE_SNPRINTF + /* The SNPRINTF result is appended after result[0..length]. + The latter is an array of DCHAR_T; SNPRINTF appends an + array of TCHAR_T to it. This is possible because + sizeof (TCHAR_T) divides sizeof (DCHAR_T) and + alignof (TCHAR_T) <= alignof (DCHAR_T). */ +# define TCHARS_PER_DCHAR (sizeof (DCHAR_T) / sizeof (TCHAR_T)) + /* Ensure that maxlen below will be >= 2. Needed on BeOS, + where an snprintf() with maxlen==1 acts like sprintf(). */ + ENSURE_ALLOCATION (xsum (length, + (2 + TCHARS_PER_DCHAR - 1) + / TCHARS_PER_DCHAR)); + /* Prepare checking whether snprintf returns the count + via %n. */ + *(TCHAR_T *) (result + length) = '\0'; +#endif + + for (;;) + { + int count = -1; + +#if USE_SNPRINTF + int retcount = 0; + size_t maxlen = allocated - length; + /* SNPRINTF can fail if its second argument is + > INT_MAX. */ + if (maxlen > INT_MAX / TCHARS_PER_DCHAR) + maxlen = INT_MAX / TCHARS_PER_DCHAR; + maxlen = maxlen * TCHARS_PER_DCHAR; +# define SNPRINTF_BUF(arg) \ + switch (prefix_count) \ + { \ + case 0: \ + retcount = SNPRINTF ((TCHAR_T *) (result + length), \ + maxlen, buf, \ + arg, &count); \ + break; \ + case 1: \ + retcount = SNPRINTF ((TCHAR_T *) (result + length), \ + maxlen, buf, \ + prefixes[0], arg, &count); \ + break; \ + case 2: \ + retcount = SNPRINTF ((TCHAR_T *) (result + length), \ + maxlen, buf, \ + prefixes[0], prefixes[1], arg, \ + &count); \ + break; \ + default: \ + abort (); \ + } +#else +# define SNPRINTF_BUF(arg) \ + switch (prefix_count) \ + { \ + case 0: \ + count = sprintf (tmp, buf, arg); \ + break; \ + case 1: \ + count = sprintf (tmp, buf, prefixes[0], arg); \ + break; \ + case 2: \ + count = sprintf (tmp, buf, prefixes[0], prefixes[1],\ + arg); \ + break; \ + default: \ + abort (); \ + } +#endif + + switch (type) + { + case TYPE_SCHAR: + { + int arg = a.arg[dp->arg_index].a.a_schar; + SNPRINTF_BUF (arg); + } + break; + case TYPE_UCHAR: + { + unsigned int arg = a.arg[dp->arg_index].a.a_uchar; + SNPRINTF_BUF (arg); + } + break; + case TYPE_SHORT: + { + int arg = a.arg[dp->arg_index].a.a_short; + SNPRINTF_BUF (arg); + } + break; + case TYPE_USHORT: + { + unsigned int arg = a.arg[dp->arg_index].a.a_ushort; + SNPRINTF_BUF (arg); + } + break; + case TYPE_INT: + { + int arg = a.arg[dp->arg_index].a.a_int; + SNPRINTF_BUF (arg); + } + break; + case TYPE_UINT: + { + unsigned int arg = a.arg[dp->arg_index].a.a_uint; + SNPRINTF_BUF (arg); + } + break; + case TYPE_LONGINT: + { + long int arg = a.arg[dp->arg_index].a.a_longint; + SNPRINTF_BUF (arg); + } + break; + case TYPE_ULONGINT: + { + unsigned long int arg = a.arg[dp->arg_index].a.a_ulongint; + SNPRINTF_BUF (arg); + } + break; +#if HAVE_LONG_LONG_INT + case TYPE_LONGLONGINT: + { + long long int arg = a.arg[dp->arg_index].a.a_longlongint; + SNPRINTF_BUF (arg); + } + break; + case TYPE_ULONGLONGINT: + { + unsigned long long int arg = a.arg[dp->arg_index].a.a_ulonglongint; + SNPRINTF_BUF (arg); + } + break; +#endif + case TYPE_DOUBLE: + { + double arg = a.arg[dp->arg_index].a.a_double; + SNPRINTF_BUF (arg); + } + break; + case TYPE_LONGDOUBLE: + { + long double arg = a.arg[dp->arg_index].a.a_longdouble; + SNPRINTF_BUF (arg); + } + break; + case TYPE_CHAR: + { + int arg = a.arg[dp->arg_index].a.a_char; + SNPRINTF_BUF (arg); + } + break; +#if HAVE_WINT_T + case TYPE_WIDE_CHAR: + { + wint_t arg = a.arg[dp->arg_index].a.a_wide_char; + SNPRINTF_BUF (arg); + } + break; +#endif + case TYPE_STRING: + { + const char *arg = a.arg[dp->arg_index].a.a_string; + SNPRINTF_BUF (arg); + } + break; +#if HAVE_WCHAR_T + case TYPE_WIDE_STRING: + { + const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string; + SNPRINTF_BUF (arg); + } + break; +#endif + case TYPE_POINTER: + { + void *arg = a.arg[dp->arg_index].a.a_pointer; + SNPRINTF_BUF (arg); + } + break; + default: + abort (); + } + +#if USE_SNPRINTF + /* Portability: Not all implementations of snprintf() + are ISO C 99 compliant. Determine the number of + bytes that snprintf() has produced or would have + produced. */ + if (count >= 0) + { + /* Verify that snprintf() has NUL-terminated its + result. */ + if (count < maxlen + && ((TCHAR_T *) (result + length)) [count] != '\0') + abort (); + /* Portability hack. */ + if (retcount > count) + count = retcount; + } + else + { + /* snprintf() doesn't understand the '%n' + directive. */ + if (fbp[1] != '\0') + { + /* Don't use the '%n' directive; instead, look + at the snprintf() return value. */ + fbp[1] = '\0'; + continue; + } + else + { + /* Look at the snprintf() return value. */ + if (retcount < 0) + { + /* HP-UX 10.20 snprintf() is doubly deficient: + It doesn't understand the '%n' directive, + *and* it returns -1 (rather than the length + that would have been required) when the + buffer is too small. */ + size_t bigger_need = + xsum (xtimes (allocated, 2), 12); + ENSURE_ALLOCATION (bigger_need); + continue; + } + else + count = retcount; + } + } +#endif + + /* Attempt to handle failure. */ + if (count < 0) + { + if (!(result == resultbuf || result == NULL)) + free (result); + if (buf_malloced != NULL) + free (buf_malloced); + CLEANUP (); + errno = EINVAL; + return NULL; + } + +#if USE_SNPRINTF + /* Handle overflow of the allocated buffer. + If such an overflow occurs, a C99 compliant snprintf() + returns a count >= maxlen. However, a non-compliant + snprintf() function returns only count = maxlen - 1. To + cover both cases, test whether count >= maxlen - 1. */ + if ((unsigned int) count + 1 >= maxlen) + { + /* If maxlen already has attained its allowed maximum, + allocating more memory will not increase maxlen. + Instead of looping, bail out. */ + if (maxlen == INT_MAX / TCHARS_PER_DCHAR) + goto overflow; + else + { + /* Need at least (count + 1) * sizeof (TCHAR_T) + bytes. (The +1 is for the trailing NUL.) + But ask for (count + 2) * sizeof (TCHAR_T) + bytes, so that in the next round, we likely get + maxlen > (unsigned int) count + 1 + and so we don't get here again. + And allocate proportionally, to avoid looping + eternally if snprintf() reports a too small + count. */ + size_t n = + xmax (xsum (length, + ((unsigned int) count + 2 + + TCHARS_PER_DCHAR - 1) + / TCHARS_PER_DCHAR), + xtimes (allocated, 2)); + + ENSURE_ALLOCATION (n); + continue; + } + } +#endif + +#if NEED_PRINTF_UNBOUNDED_PRECISION + if (prec_ourselves) + { + /* Handle the precision. */ + TCHAR_T *prec_ptr = +# if USE_SNPRINTF + (TCHAR_T *) (result + length); +# else + tmp; +# endif + size_t prefix_count; + size_t move; + + prefix_count = 0; + /* Put the additional zeroes after the sign. */ + if (count >= 1 + && (*prec_ptr == '-' || *prec_ptr == '+' + || *prec_ptr == ' ')) + prefix_count = 1; + /* Put the additional zeroes after the 0x prefix if + (flags & FLAG_ALT) || (dp->conversion == 'p'). */ + else if (count >= 2 + && prec_ptr[0] == '0' + && (prec_ptr[1] == 'x' || prec_ptr[1] == 'X')) + prefix_count = 2; + + move = count - prefix_count; + if (precision > move) + { + /* Insert zeroes. */ + size_t insert = precision - move; + TCHAR_T *prec_end; + +# if USE_SNPRINTF + size_t n = + xsum (length, + (count + insert + TCHARS_PER_DCHAR - 1) + / TCHARS_PER_DCHAR); + length += (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR; + ENSURE_ALLOCATION (n); + length -= (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR; + prec_ptr = (TCHAR_T *) (result + length); +# endif + + prec_end = prec_ptr + count; + prec_ptr += prefix_count; + + while (prec_end > prec_ptr) + { + prec_end--; + prec_end[insert] = prec_end[0]; + } + + prec_end += insert; + do + *--prec_end = '0'; + while (prec_end > prec_ptr); + + count += insert; + } + } +#endif + +#if !USE_SNPRINTF + if (count >= tmp_length) + /* tmp_length was incorrectly calculated - fix the + code above! */ + abort (); +#endif + +#if !DCHAR_IS_TCHAR + /* Convert from TCHAR_T[] to DCHAR_T[]. */ + if (dp->conversion == 'c' || dp->conversion == 's') + { + /* type = TYPE_CHAR or TYPE_WIDE_CHAR or TYPE_STRING + TYPE_WIDE_STRING. + The result string is not certainly ASCII. */ + const TCHAR_T *tmpsrc; + DCHAR_T *tmpdst; + size_t tmpdst_len; + /* This code assumes that TCHAR_T is 'char'. */ + typedef int TCHAR_T_verify + [2 * (sizeof (TCHAR_T) == 1) - 1]; +# if USE_SNPRINTF + tmpsrc = (TCHAR_T *) (result + length); +# else + tmpsrc = tmp; +# endif + tmpdst = + DCHAR_CONV_FROM_ENCODING (locale_charset (), + iconveh_question_mark, + tmpsrc, count, + NULL, + NULL, &tmpdst_len); + if (tmpdst == NULL) + { + int saved_errno = errno; + if (!(result == resultbuf || result == NULL)) + free (result); + if (buf_malloced != NULL) + free (buf_malloced); + CLEANUP (); + errno = saved_errno; + return NULL; + } + ENSURE_ALLOCATION (xsum (length, tmpdst_len)); + DCHAR_CPY (result + length, tmpdst, tmpdst_len); + free (tmpdst); + count = tmpdst_len; + } + else + { + /* The result string is ASCII. + Simple 1:1 conversion. */ +# if USE_SNPRINTF + /* If sizeof (DCHAR_T) == sizeof (TCHAR_T), it's a + no-op conversion, in-place on the array starting + at (result + length). */ + if (sizeof (DCHAR_T) != sizeof (TCHAR_T)) +# endif + { + const TCHAR_T *tmpsrc; + DCHAR_T *tmpdst; + size_t n; + +# if USE_SNPRINTF + if (result == resultbuf) + { + tmpsrc = (TCHAR_T *) (result + length); + /* ENSURE_ALLOCATION will not move tmpsrc + (because it's part of resultbuf). */ + ENSURE_ALLOCATION (xsum (length, count)); + } + else + { + /* ENSURE_ALLOCATION will move the array + (because it uses realloc(). */ + ENSURE_ALLOCATION (xsum (length, count)); + tmpsrc = (TCHAR_T *) (result + length); + } +# else + tmpsrc = tmp; + ENSURE_ALLOCATION (xsum (length, count)); +# endif + tmpdst = result + length; + /* Copy backwards, because of overlapping. */ + tmpsrc += count; + tmpdst += count; + for (n = count; n > 0; n--) + *--tmpdst = (unsigned char) *--tmpsrc; + } + } +#endif + +#if DCHAR_IS_TCHAR && !USE_SNPRINTF + /* Make room for the result. */ + if (count > allocated - length) + { + /* Need at least count elements. But allocate + proportionally. */ + size_t n = + xmax (xsum (length, count), xtimes (allocated, 2)); + + ENSURE_ALLOCATION (n); + } +#endif + + /* Here count <= allocated - length. */ + + /* Perform padding. */ +#if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION + if (pad_ourselves && has_width) + { + size_t w; +# if ENABLE_UNISTDIO + /* Outside POSIX, it's preferrable to compare the width + against the number of _characters_ of the converted + value. */ + w = DCHAR_MBSNLEN (result + length, count); +# else + /* The width is compared against the number of _bytes_ + of the converted value, says POSIX. */ + w = count; +# endif + if (w < width) + { + size_t pad = width - w; + + /* Make room for the result. */ + if (xsum (count, pad) > allocated - length) + { + /* Need at least count + pad elements. But + allocate proportionally. */ + size_t n = + xmax (xsum3 (length, count, pad), + xtimes (allocated, 2)); + +# if USE_SNPRINTF + length += count; + ENSURE_ALLOCATION (n); + length -= count; +# else + ENSURE_ALLOCATION (n); +# endif + } + /* Here count + pad <= allocated - length. */ + + { +# if !DCHAR_IS_TCHAR || USE_SNPRINTF + DCHAR_T * const rp = result + length; +# else + DCHAR_T * const rp = tmp; +# endif + DCHAR_T *p = rp + count; + DCHAR_T *end = p + pad; + DCHAR_T *pad_ptr; +# if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO + if (dp->conversion == 'c' + || dp->conversion == 's') + /* No zero-padding for string directives. */ + pad_ptr = NULL; + else +# endif + { + pad_ptr = (*rp == '-' ? rp + 1 : rp); + /* No zero-padding of "inf" and "nan". */ + if ((*pad_ptr >= 'A' && *pad_ptr <= 'Z') + || (*pad_ptr >= 'a' && *pad_ptr <= 'z')) + pad_ptr = NULL; + } + /* The generated string now extends from rp to p, + with the zero padding insertion point being at + pad_ptr. */ + + count = count + pad; /* = end - rp */ + + if (flags & FLAG_LEFT) + { + /* Pad with spaces on the right. */ + for (; pad > 0; pad--) + *p++ = ' '; + } + else if ((flags & FLAG_ZERO) && pad_ptr != NULL) + { + /* Pad with zeroes. */ + DCHAR_T *q = end; + + while (p > pad_ptr) + *--q = *--p; + for (; pad > 0; pad--) + *p++ = '0'; + } + else + { + /* Pad with spaces on the left. */ + DCHAR_T *q = end; + + while (p > rp) + *--q = *--p; + for (; pad > 0; pad--) + *p++ = ' '; + } + } + } + } +#endif + + /* Here still count <= allocated - length. */ + +#if !DCHAR_IS_TCHAR || USE_SNPRINTF + /* The snprintf() result did fit. */ +#else + /* Append the sprintf() result. */ + memcpy (result + length, tmp, count * sizeof (DCHAR_T)); +#endif +#if !USE_SNPRINTF + if (tmp != tmpbuf) + free (tmp); +#endif + +#if NEED_PRINTF_DIRECTIVE_F + if (dp->conversion == 'F') + { + /* Convert the %f result to upper case for %F. */ + DCHAR_T *rp = result + length; + size_t rc; + for (rc = count; rc > 0; rc--, rp++) + if (*rp >= 'a' && *rp <= 'z') + *rp = *rp - 'a' + 'A'; + } +#endif + + length += count; + break; + } + } + } + } + + /* Add the final NUL. */ + ENSURE_ALLOCATION (xsum (length, 1)); + result[length] = '\0'; + + if (result != resultbuf && length + 1 < allocated) + { + /* Shrink the allocated memory if possible. */ + DCHAR_T *memory; + + memory = (DCHAR_T *) realloc (result, (length + 1) * sizeof (DCHAR_T)); + if (memory != NULL) + result = memory; + } + + if (buf_malloced != NULL) + free (buf_malloced); + CLEANUP (); + *lengthp = length; + /* Note that we can produce a big string of a length > INT_MAX. POSIX + says that snprintf() fails with errno = EOVERFLOW in this case, but + that's only because snprintf() returns an 'int'. This function does + not have this limitation. */ + return result; + +#if USE_SNPRINTF + overflow: + if (!(result == resultbuf || result == NULL)) + free (result); + if (buf_malloced != NULL) + free (buf_malloced); + CLEANUP (); + errno = EOVERFLOW; + return NULL; +#endif + + out_of_memory: + if (!(result == resultbuf || result == NULL)) + free (result); + if (buf_malloced != NULL) + free (buf_malloced); + out_of_memory_1: + CLEANUP (); + errno = ENOMEM; + return NULL; + } +} + +#undef TCHARS_PER_DCHAR +#undef SNPRINTF +#undef USE_SNPRINTF +#undef DCHAR_CPY +#undef PRINTF_PARSE +#undef DIRECTIVES +#undef DIRECTIVE +#undef DCHAR_IS_TCHAR +#undef TCHAR_T +#undef DCHAR_T +#undef FCHAR_T +#undef VASNPRINTF diff --git a/lib/vasnprintf.h b/lib/vasnprintf.h new file mode 100644 index 000000000..5ceab4475 --- /dev/null +++ b/lib/vasnprintf.h @@ -0,0 +1,81 @@ +/* vsprintf with automatic memory allocation. + Copyright (C) 2002-2004, 2007-2008 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2, 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License along + with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef _VASNPRINTF_H +#define _VASNPRINTF_H + +/* Get va_list. */ +#include + +/* Get size_t. */ +#include + +#ifndef __attribute__ +/* This feature is available in gcc versions 2.5 and later. */ +# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) +# define __attribute__(Spec) /* empty */ +# endif +/* The __-protected variants of `format' and `printf' attributes + are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */ +# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) +# define __format__ format +# define __printf__ printf +# endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* Write formatted output to a string dynamically allocated with malloc(). + You can pass a preallocated buffer for the result in RESULTBUF and its + size in *LENGTHP; otherwise you pass RESULTBUF = NULL. + If successful, return the address of the string (this may be = RESULTBUF + if no dynamic memory allocation was necessary) and set *LENGTHP to the + number of resulting bytes, excluding the trailing NUL. Upon error, set + errno and return NULL. + + When dynamic memory allocation occurs, the preallocated buffer is left + alone (with possibly modified contents). This makes it possible to use + a statically allocated or stack-allocated buffer, like this: + + char buf[100]; + size_t len = sizeof (buf); + char *output = vasnprintf (buf, &len, format, args); + if (output == NULL) + ... error handling ...; + else + { + ... use the output string ...; + if (output != buf) + free (output); + } + */ +#if REPLACE_VASNPRINTF +# define asnprintf rpl_asnprintf +# define vasnprintf rpl_vasnprintf +#endif +extern char * asnprintf (char *resultbuf, size_t *lengthp, const char *format, ...) + __attribute__ ((__format__ (__printf__, 3, 4))); +extern char * vasnprintf (char *resultbuf, size_t *lengthp, const char *format, va_list args) + __attribute__ ((__format__ (__printf__, 3, 0))); + +#ifdef __cplusplus +} +#endif + +#endif /* _VASNPRINTF_H */ diff --git a/lib/verify.h b/lib/verify.h new file mode 100644 index 000000000..e82fa02d9 --- /dev/null +++ b/lib/verify.h @@ -0,0 +1,140 @@ +/* Compile-time assert-like macros. + + Copyright (C) 2005, 2006 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +/* Written by Paul Eggert, Bruno Haible, and Jim Meyering. */ + +#ifndef VERIFY_H +# define VERIFY_H 1 + +/* Each of these macros verifies that its argument R is nonzero. To + be portable, R should be an integer constant expression. Unlike + assert (R), there is no run-time overhead. + + There are two macros, since no single macro can be used in all + contexts in C. verify_true (R) is for scalar contexts, including + integer constant expression contexts. verify (R) is for declaration + contexts, e.g., the top level. + + Symbols ending in "__" are private to this header. + + The code below uses several ideas. + + * The first step is ((R) ? 1 : -1). Given an expression R, of + integral or boolean or floating-point type, this yields an + expression of integral type, whose value is later verified to be + constant and nonnegative. + + * Next this expression W is wrapped in a type + struct verify_type__ { unsigned int verify_error_if_negative_size__: W; }. + If W is negative, this yields a compile-time error. No compiler can + deal with a bit-field of negative size. + + One might think that an array size check would have the same + effect, that is, that the type struct { unsigned int dummy[W]; } + would work as well. However, inside a function, some compilers + (such as C++ compilers and GNU C) allow local parameters and + variables inside array size expressions. With these compilers, + an array size check would not properly diagnose this misuse of + the verify macro: + + void function (int n) { verify (n < 0); } + + * For the verify macro, the struct verify_type__ will need to + somehow be embedded into a declaration. To be portable, this + declaration must declare an object, a constant, a function, or a + typedef name. If the declared entity uses the type directly, + such as in + + struct dummy {...}; + typedef struct {...} dummy; + extern struct {...} *dummy; + extern void dummy (struct {...} *); + extern struct {...} *dummy (void); + + two uses of the verify macro would yield colliding declarations + if the entity names are not disambiguated. A workaround is to + attach the current line number to the entity name: + + #define GL_CONCAT0(x, y) x##y + #define GL_CONCAT(x, y) GL_CONCAT0 (x, y) + extern struct {...} * GL_CONCAT(dummy,__LINE__); + + But this has the problem that two invocations of verify from + within the same macro would collide, since the __LINE__ value + would be the same for both invocations. + + A solution is to use the sizeof operator. It yields a number, + getting rid of the identity of the type. Declarations like + + extern int dummy [sizeof (struct {...})]; + extern void dummy (int [sizeof (struct {...})]); + extern int (*dummy (void)) [sizeof (struct {...})]; + + can be repeated. + + * Should the implementation use a named struct or an unnamed struct? + Which of the following alternatives can be used? + + extern int dummy [sizeof (struct {...})]; + extern int dummy [sizeof (struct verify_type__ {...})]; + extern void dummy (int [sizeof (struct {...})]); + extern void dummy (int [sizeof (struct verify_type__ {...})]); + extern int (*dummy (void)) [sizeof (struct {...})]; + extern int (*dummy (void)) [sizeof (struct verify_type__ {...})]; + + In the second and sixth case, the struct type is exported to the + outer scope; two such declarations therefore collide. GCC warns + about the first, third, and fourth cases. So the only remaining + possibility is the fifth case: + + extern int (*dummy (void)) [sizeof (struct {...})]; + + * This implementation exploits the fact that GCC does not warn about + the last declaration mentioned above. If a future version of GCC + introduces a warning for this, the problem could be worked around + by using code specialized to GCC, e.g.,: + + #if 4 <= __GNUC__ + # define verify(R) \ + extern int (* verify_function__ (void)) \ + [__builtin_constant_p (R) && (R) ? 1 : -1] + #endif + + * In C++, any struct definition inside sizeof is invalid. + Use a template type to work around the problem. */ + + +/* Verify requirement R at compile-time, as an integer constant expression. + Return 1. */ + +# ifdef __cplusplus +template + struct verify_type__ { unsigned int verify_error_if_negative_size__: w; }; +# define verify_true(R) \ + (!!sizeof (verify_type__<(R) ? 1 : -1>)) +# else +# define verify_true(R) \ + (!!sizeof \ + (struct { unsigned int verify_error_if_negative_size__: (R) ? 1 : -1; })) +# endif + +/* Verify requirement R at compile-time, as a declaration without a + trailing ';'. */ + +# define verify(R) extern int (* verify_function__ (void)) [verify_true (R)] + +#endif diff --git a/lib/vsnprintf.c b/lib/vsnprintf.c new file mode 100644 index 000000000..1fdfb6bc8 --- /dev/null +++ b/lib/vsnprintf.c @@ -0,0 +1,71 @@ +/* Formatted output to strings. + Copyright (C) 2004, 2006-2008 Free Software Foundation, Inc. + Written by Simon Josefsson and Yoann Vandoorselaere . + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2, 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License along + with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +/* Specification. */ +#include + +#include +#include +#include +#include +#include + +#include "vasnprintf.h" + +/* Print formatted output to string STR. Similar to vsprintf, but + additional length SIZE limit how much is written into STR. Returns + string length of formatted string (which may be larger than SIZE). + STR may be NULL, in which case nothing will be written. On error, + return a negative value. */ +int +vsnprintf (char *str, size_t size, const char *format, va_list args) +{ + char *output; + size_t len; + size_t lenbuf = size; + + output = vasnprintf (str, &lenbuf, format, args); + len = lenbuf; + + if (!output) + return -1; + + if (output != str) + { + if (size) + { + size_t pruned_len = (len < size ? len : size - 1); + memcpy (str, output, pruned_len); + str[pruned_len] = '\0'; + } + + free (output); + } + + if (len > INT_MAX) + { + errno = EOVERFLOW; + return -1; + } + + return len; +} diff --git a/lib/wchar.in.h b/lib/wchar.in.h index 3425062ab..1f1f13098 100644 --- a/lib/wchar.in.h +++ b/lib/wchar.in.h @@ -1,6 +1,6 @@ /* A substitute for ISO C99 , for platforms that have issues. - Copyright (C) 2007-2008 Free Software Foundation, Inc. + Copyright (C) 2007-2009 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by @@ -30,8 +30,18 @@ @PRAGMA_SYSTEM_HEADER@ #endif -#ifdef __need_mbstate_t -/* Special invocation convention inside uClibc header files. */ +#if defined __need_mbstate_t || (defined __hpux && ((defined _INTTYPES_INCLUDED && !defined strtoimax) || defined _GL_JUST_INCLUDE_SYSTEM_WCHAR_H)) || defined _GL_ALREADY_INCLUDING_WCHAR_H +/* Special invocation convention: + - Inside uClibc header files. + - On HP-UX 11.00 we have a sequence of nested includes + -> -> , and the latter includes , + once indirectly -> -> -> + and once directly. In both situations 'wint_t' is not yet defined, + therefore we cannot provide the function overrides; instead include only + the system's . + - On IRIX 6.5, similarly, we have an include -> , and + the latter includes . But here, we have no way to detect whether + is completely included or is still being included. */ #@INCLUDE_NEXT@ @NEXT_WCHAR_H@ @@ -40,6 +50,8 @@ #ifndef _GL_WCHAR_H +#define _GL_ALREADY_INCLUDING_WCHAR_H + /* Tru64 with Desktop Toolkit C has a bug: must be included before . BSD/OS 4.0.1 has a bug: , and must be @@ -55,6 +67,8 @@ # @INCLUDE_NEXT@ @NEXT_WCHAR_H@ #endif +#undef _GL_ALREADY_INCLUDING_WCHAR_H + #ifndef _GL_WCHAR_H #define _GL_WCHAR_H @@ -250,7 +264,11 @@ extern size_t wcsrtombs (char *dest, const wchar_t **srcp, size_t len, mbstate_t /* Convert a wide string to a string. */ #if @GNULIB_WCSNRTOMBS@ -# if !@HAVE_WCSNRTOMBS@ +# if @REPLACE_WCSNRTOMBS@ +# undef wcsnrtombs +# define wcsnrtombs rpl_wcsnrtombs +# endif +# if !@HAVE_WCSNRTOMBS@ || @REPLACE_WCSNRTOMBS@ extern size_t wcsnrtombs (char *dest, const wchar_t **srcp, size_t srclen, size_t len, mbstate_t *ps); # endif #elif defined GNULIB_POSIXCHECK diff --git a/lib/xsize.h b/lib/xsize.h new file mode 100644 index 000000000..0b30045e8 --- /dev/null +++ b/lib/xsize.h @@ -0,0 +1,108 @@ +/* xsize.h -- Checked size_t computations. + + Copyright (C) 2003, 2008 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2, 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef _XSIZE_H +#define _XSIZE_H + +/* Get size_t. */ +#include + +/* Get SIZE_MAX. */ +#include +#if HAVE_STDINT_H +# include +#endif + +/* The size of memory objects is often computed through expressions of + type size_t. Example: + void* p = malloc (header_size + n * element_size). + These computations can lead to overflow. When this happens, malloc() + returns a piece of memory that is way too small, and the program then + crashes while attempting to fill the memory. + To avoid this, the functions and macros in this file check for overflow. + The convention is that SIZE_MAX represents overflow. + malloc (SIZE_MAX) is not guaranteed to fail -- think of a malloc + implementation that uses mmap --, it's recommended to use size_overflow_p() + or size_in_bounds_p() before invoking malloc(). + The example thus becomes: + size_t size = xsum (header_size, xtimes (n, element_size)); + void *p = (size_in_bounds_p (size) ? malloc (size) : NULL); +*/ + +/* Convert an arbitrary value >= 0 to type size_t. */ +#define xcast_size_t(N) \ + ((N) <= SIZE_MAX ? (size_t) (N) : SIZE_MAX) + +/* Sum of two sizes, with overflow check. */ +static inline size_t +#if __GNUC__ >= 3 +__attribute__ ((__pure__)) +#endif +xsum (size_t size1, size_t size2) +{ + size_t sum = size1 + size2; + return (sum >= size1 ? sum : SIZE_MAX); +} + +/* Sum of three sizes, with overflow check. */ +static inline size_t +#if __GNUC__ >= 3 +__attribute__ ((__pure__)) +#endif +xsum3 (size_t size1, size_t size2, size_t size3) +{ + return xsum (xsum (size1, size2), size3); +} + +/* Sum of four sizes, with overflow check. */ +static inline size_t +#if __GNUC__ >= 3 +__attribute__ ((__pure__)) +#endif +xsum4 (size_t size1, size_t size2, size_t size3, size_t size4) +{ + return xsum (xsum (xsum (size1, size2), size3), size4); +} + +/* Maximum of two sizes, with overflow check. */ +static inline size_t +#if __GNUC__ >= 3 +__attribute__ ((__pure__)) +#endif +xmax (size_t size1, size_t size2) +{ + /* No explicit check is needed here, because for any n: + max (SIZE_MAX, n) == SIZE_MAX and max (n, SIZE_MAX) == SIZE_MAX. */ + return (size1 >= size2 ? size1 : size2); +} + +/* Multiplication of a count with an element size, with overflow check. + The count must be >= 0 and the element size must be > 0. + This is a macro, not an inline function, so that it works correctly even + when N is of a wider type and N > SIZE_MAX. */ +#define xtimes(N, ELSIZE) \ + ((N) <= SIZE_MAX / (ELSIZE) ? (size_t) (N) * (ELSIZE) : SIZE_MAX) + +/* Check for overflow. */ +#define size_overflow_p(SIZE) \ + ((SIZE) == SIZE_MAX) +/* Check against overflow. */ +#define size_in_bounds_p(SIZE) \ + ((SIZE) != SIZE_MAX) + +#endif /* _XSIZE_H */ diff --git a/libguile.h b/libguile.h index 40122dfa2..7b5649b8f 100644 --- a/libguile.h +++ b/libguile.h @@ -1,21 +1,22 @@ #ifndef SCM_LIBGUILE_H #define SCM_LIBGUILE_H -/* Copyright (C) 1995,1996,1997,1998,2000,2001, 2002, 2003, 2004, 2006, 2008 Free Software Foundation, Inc. +/* Copyright (C) 1995,1996,1997,1998,2000,2001, 2002, 2003, 2004, 2006, 2008, 2009 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ @@ -32,6 +33,7 @@ extern "C" { #include "libguile/arbiters.h" #include "libguile/async.h" #include "libguile/boolean.h" +#include "libguile/bytevectors.h" #include "libguile/chars.h" #include "libguile/continuations.h" #include "libguile/dynl.h" @@ -75,6 +77,7 @@ extern "C" { #include "libguile/procprop.h" #include "libguile/properties.h" #include "libguile/procs.h" +#include "libguile/r6rs-ports.h" #include "libguile/ramap.h" #include "libguile/random.h" #include "libguile/read.h" diff --git a/libguile/Makefile.am b/libguile/Makefile.am index dda3994a3..f000f8332 100644 --- a/libguile/Makefile.am +++ b/libguile/Makefile.am @@ -1,23 +1,23 @@ ## Process this file with Automake to create Makefile.in ## -## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008 Free Software Foundation, Inc. +## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. ## ## This file is part of GUILE. ## -## GUILE 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, or +## GUILE is free software; you can redistribute it and/or modify it +## under the terms of the GNU Lesser General Public License as +## published by the Free Software Foundation; either version 3, or ## (at your option) any later version. ## ## GUILE 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. +## GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU General Public -## License along with GUILE; see the file COPYING. If not, write -## to the Free Software Foundation, Inc., 51 Franklin Street, Fifth -## Floor, Boston, MA 02110-1301 USA +## You should have received a copy of the GNU Lesser General Public +## License along with GUILE; see the file COPYING.LESSER. If not, +## write to the Free Software Foundation, Inc., 51 Franklin Street, +## Fifth Floor, Boston, MA 02110-1301 USA AUTOMAKE_OPTIONS = gnu @@ -32,10 +32,10 @@ DEFAULT_INCLUDES = ## Check for headers in $(srcdir)/.., so that #include ## will find MUMBLE.h in this dir when we're ## building. Also look for Gnulib headers in `lib'. -AM_CPPFLAGS = -I$(top_srcdir) -I$(top_builddir) \ +AM_CPPFLAGS = -DBUILDING_LIBGUILE=1 -I$(top_srcdir) -I$(top_builddir) \ -I$(top_srcdir)/lib -I$(top_builddir)/lib -AM_CFLAGS = $(GCC_CFLAGS) +AM_CFLAGS = $(GCC_CFLAGS) $(CFLAG_VISIBILITY) ## The Gnulib Libtool archive. gnulib_library = $(top_builddir)/lib/libgnu.la @@ -106,7 +106,8 @@ guile_LDFLAGS = $(GUILE_CFLAGS) libguile_la_CFLAGS = $(GUILE_CFLAGS) $(AM_CFLAGS) libguile_la_SOURCES = alist.c arbiters.c async.c backtrace.c boolean.c \ - chars.c continuations.c convert.c debug.c deprecation.c \ + bytevectors.c chars.c continuations.c \ + convert.c debug.c deprecation.c \ deprecated.c discouraged.c dynwind.c eq.c error.c \ eval.c evalext.c extensions.c feature.c fluids.c fports.c \ futures.c gc.c gc-malloc.c \ @@ -114,7 +115,8 @@ libguile_la_SOURCES = alist.c arbiters.c async.c backtrace.c boolean.c \ guardians.c hash.c hashtab.c hooks.c init.c inline.c \ ioext.c keywords.c lang.c list.c load.c macros.c mallocs.c \ modules.c numbers.c objects.c objprop.c options.c pairs.c ports.c \ - print.c procprop.c procs.c properties.c random.c rdelim.c read.c \ + print.c procprop.c procs.c properties.c \ + r6rs-ports.c random.c rdelim.c read.c \ root.c rw.c scmsigs.c script.c simpos.c smob.c sort.c srcprop.c \ stackchk.c stacks.c stime.c strings.c srfi-4.c srfi-13.c srfi-14.c \ strorder.c strports.c struct.c symbols.c threads.c null-threads.c \ @@ -133,7 +135,8 @@ libguile_i18n_v_@LIBGUILE_I18N_MAJOR@_la_LDFLAGS = \ -module -L$(builddir) -lguile \ -version-info @LIBGUILE_I18N_INTERFACE@ -DOT_X_FILES = alist.x arbiters.x async.x backtrace.x boolean.x chars.x \ +DOT_X_FILES = alist.x arbiters.x async.x backtrace.x boolean.x \ + bytevectors.x chars.x \ continuations.x debug.x deprecation.x deprecated.x discouraged.x \ dynl.x dynwind.x environments.x eq.x error.x eval.x evalext.x \ extensions.x feature.x fluids.x fports.x futures.x gc.x \ @@ -141,7 +144,8 @@ DOT_X_FILES = alist.x arbiters.x async.x backtrace.x boolean.x chars.x \ hash.x hashtab.x hooks.x i18n.x init.x ioext.x keywords.x lang.x \ list.x load.x macros.x mallocs.x modules.x numbers.x objects.x \ objprop.x options.x pairs.x ports.x print.x procprop.x procs.x \ - properties.x random.x rdelim.x read.x root.x rw.x scmsigs.x \ + properties.x r6rs-ports.x random.x rdelim.x \ + read.x root.x rw.x scmsigs.x \ script.x simpos.x smob.x sort.x srcprop.x stackchk.x stacks.x \ stime.x strings.x srfi-4.x srfi-13.x srfi-14.x strorder.x \ strports.x struct.x symbols.x threads.x throw.x values.x \ @@ -153,7 +157,8 @@ DOT_X_FILES += frames.x instructions.x objcodes.x programs.x vm.x EXTRA_DOT_X_FILES = @EXTRA_DOT_X_FILES@ DOT_DOC_FILES = alist.doc arbiters.doc async.doc backtrace.doc \ - boolean.doc chars.doc continuations.doc debug.doc deprecation.doc \ + boolean.doc bytevectors.doc chars.doc \ + continuations.doc debug.doc deprecation.doc \ deprecated.doc discouraged.doc dynl.doc dynwind.doc \ eq.doc error.doc eval.doc evalext.doc \ extensions.doc feature.doc fluids.doc fports.doc futures.doc \ @@ -162,7 +167,8 @@ DOT_DOC_FILES = alist.doc arbiters.doc async.doc backtrace.doc \ hooks.doc i18n.doc init.doc ioext.doc keywords.doc lang.doc \ list.doc load.doc macros.doc mallocs.doc modules.doc numbers.doc \ objects.doc objprop.doc options.doc pairs.doc ports.doc print.doc \ - procprop.doc procs.doc properties.doc random.doc rdelim.doc \ + procprop.doc procs.doc properties.doc r6rs-ports.doc \ + random.doc rdelim.doc \ read.doc root.doc rw.doc scmsigs.doc script.doc simpos.doc \ smob.doc sort.doc srcprop.doc stackchk.doc stacks.doc stime.doc \ strings.doc srfi-4.doc srfi-13.doc srfi-14.doc strorder.doc \ @@ -201,7 +207,7 @@ install-exec-hook: ## working. noinst_HEADERS = convert.i.c \ conv-integer.i.c conv-uinteger.i.c \ - eval.i.c \ + eval.i.c ieee-754.h \ srfi-4.i.c \ quicksort.i.c \ win32-uname.h win32-dirent.h win32-socket.h \ @@ -211,16 +217,23 @@ noinst_HEADERS = convert.i.c \ noinst_HEADERS += vm-engine.c vm-i-system.c vm-i-scheme.c vm-i-loader.c libguile_la_DEPENDENCIES = @LIBLOBJS@ -libguile_la_LIBADD = @LIBLOBJS@ $(gnulib_library) +libguile_la_LIBADD = @LIBLOBJS@ $(gnulib_library) $(LTLIBGMP) $(LTLIBUNISTRING) libguile_la_LDFLAGS = @LTLIBINTL@ -version-info @LIBGUILE_INTERFACE_CURRENT@:@LIBGUILE_INTERFACE_REVISION@:@LIBGUILE_INTERFACE_AGE@ -export-dynamic -no-undefined +if HAVE_LD_VERSION_SCRIPT + +libguile_la_LDFLAGS += -Wl,--version-script="$(srcdir)/libguile.map" + +endif HAVE_LD_VERSION_SCRIPT + + # These are headers visible as pkginclude_HEADERS = # These are headers visible as . modincludedir = $(includedir)/libguile modinclude_HEADERS = __scm.h alist.h arbiters.h async.h backtrace.h \ - boehm-gc.h \ + boehm-gc.h bytevectors.h \ boolean.h chars.h continuations.h convert.h debug.h debug-malloc.h \ deprecation.h deprecated.h discouraged.h dynl.h dynwind.h \ eq.h error.h eval.h evalext.h extensions.h \ @@ -230,7 +243,8 @@ modinclude_HEADERS = __scm.h alist.h arbiters.h async.h backtrace.h \ hashtab.h hooks.h i18n.h init.h inline.h ioext.h iselect.h \ keywords.h lang.h list.h load.h macros.h mallocs.h modules.h \ net_db.h numbers.h objects.h objprop.h options.h pairs.h ports.h \ - posix.h regex-posix.h print.h procprop.h procs.h properties.h \ + posix.h r6rs-ports.h regex-posix.h print.h \ + procprop.h procs.h properties.h \ random.h ramap.h rdelim.h read.h root.h rw.h scmsigs.h validate.h \ script.h simpos.h smob.h snarf.h socket.h sort.h srcprop.h \ stackchk.h stacks.h stime.h strings.h srfi-4.h srfi-13.h srfi-14.h \ @@ -254,7 +268,7 @@ EXTRA_DIST = ChangeLog-scm ChangeLog-threads \ cpp_errno.c cpp_err_symbols.in cpp_err_symbols.c \ cpp_sig_symbols.c cpp_sig_symbols.in cpp_cnvt.awk \ c-tokenize.lex version.h.in \ - scmconfig.h.top libgettext.h measure-hwm.scm + scmconfig.h.top libgettext.h libguile.map # $(DOT_DOC_FILES) $(EXTRA_DOT_DOC_FILES) \ # guile-procedures.txt guile.texi @@ -276,6 +290,8 @@ libpath.h: $(srcdir)/Makefile.in $(top_builddir)/config.status @echo '#define SCM_PKGDATA_DIR "$(pkgdatadir)"' >> libpath.tmp @echo '#define SCM_LIBRARY_DIR "$(pkgdatadir)/$(GUILE_EFFECTIVE_VERSION)"'>>libpath.tmp @echo '#define SCM_SITE_DIR "$(pkgdatadir)/site"' >> libpath.tmp + @echo '#define SCM_CCACHE_DIR "$(pkglibdir)/$(GUILE_EFFECTIVE_VERSION)/ccache"' >> libpath.tmp + @echo '#define SCM_EFFECTIVE_VERSION "$(GUILE_EFFECTIVE_VERSION)"' >> libpath.tmp @echo '#define SCM_BUILD_INFO { \' >> libpath.tmp @echo ' { "srcdir", "'"`cd @srcdir@; pwd`"'" }, \' >> libpath.tmp @echo ' { "top_srcdir", "@top_srcdir_absolute@" }, \' >> libpath.tmp @@ -289,12 +305,13 @@ libpath.h: $(srcdir)/Makefile.in $(top_builddir)/config.status @echo ' { "sharedstatedir", "@sharedstatedir@" }, \' >> libpath.tmp @echo ' { "localstatedir", "@localstatedir@" }, \' >> libpath.tmp @echo ' { "libdir", "@libdir@" }, \' >> libpath.tmp + @echo ' { "ccachedir", SCM_CCACHE_DIR }, \' >> libpath.tmp @echo ' { "infodir", "@infodir@" }, \' >> libpath.tmp @echo ' { "mandir", "@mandir@" }, \' >> libpath.tmp @echo ' { "includedir", "@includedir@" }, \' >> libpath.tmp - @echo ' { "pkgdatadir", "$(datadir)/@PACKAGE@" }, \' >> libpath.tmp - @echo ' { "pkglibdir", "$(libdir)/@PACKAGE@" }, \' >> libpath.tmp - @echo ' { "pkgincludedir", "$(includedir)/@PACKAGE@" }, \' \ + @echo ' { "pkgdatadir", "@pkgdatadir@" }, \' >> libpath.tmp + @echo ' { "pkglibdir", "@pkglibdir@" }, \' >> libpath.tmp + @echo ' { "pkgincludedir", "@pkgincludedir@" }, \' \ >> libpath.tmp @echo ' { "guileversion", "@GUILE_VERSION@" }, \' >> libpath.tmp @echo ' { "libguileinterface", "@LIBGUILE_INTERFACE@" }, \' \ @@ -324,10 +341,8 @@ error.x: cpp_err_symbols.c posix.x: cpp_sig_symbols.c load.x: libpath.h -include $(top_srcdir)/am/pre-inst-guile - alldotdocfiles = $(DOT_DOC_FILES) $(EXTRA_DOT_DOC_FILES) -snarf2checkedtexi = GUILE="$(GUILE_FOR_BUILD)" $(top_srcdir)/scripts/snarf-check-and-output-texi +snarf2checkedtexi = GUILE_AUTO_COMPILE=0 $(top_builddir)/meta/uninstalled-env guile-tools snarf-check-and-output-texi dotdoc2texi = cat $(alldotdocfiles) | $(snarf2checkedtexi) guile.texi: $(alldotdocfiles) guile$(EXEEXT) @@ -349,29 +364,6 @@ guile-procedures.txt: guile-procedures.texi endif -# Stack limit calibration for `make check'. (For why we do this, see -# the comments in measure-hwm.scm.) We're relying here on a couple of -# bits of Automake magic. -# -# 1. The fact that "libguile" comes before "test-suite" in SUBDIRS in -# our toplevel Makefile.am. This ensures that the -# stack-limit-calibration.scm "test" will be run before any of the -# tests under test-suite. -# -# 2. The fact that each test is invoked as $TESTS_ENVIRONMENT $test. -# This allows us to ensure that the test will be considered to have -# passed, by using `true' as TESTS_ENVIRONMENT. -# -# Why don't we care about the test "actually passing"? Because the -# important thing about stack-limit-calibration.scm is just that it is -# generated in the first place, so that other tests under test-suite -# can use it. -TESTS = stack-limit-calibration.scm -TESTS_ENVIRONMENT = true - -stack-limit-calibration.scm: measure-hwm.scm guile$(EXEEXT) - $(preinstguile) -s $(srcdir)/measure-hwm.scm > $@ - c-tokenize.c: c-tokenize.lex flex -t $(srcdir)/c-tokenize.lex > $@ || { rm $@; false; } @@ -426,8 +418,9 @@ MOSTLYCLEANFILES = \ cpp_err_symbols_here cpp_err_symbols_diff cpp_err_symbols_new \ cpp_sig_symbols_here cpp_sig_symbols_diff cpp_sig_symbols_new \ version.h version.h.tmp \ - scmconfig.h scmconfig.h.tmp stack-limit-calibration.scm + scmconfig.h scmconfig.h.tmp -CLEANFILES = libpath.h *.x *.doc guile-procedures.txt guile-procedures.texi guile.texi +CLEANFILES = libpath.h *.x *.doc guile-procedures.txt guile-procedures.texi guile.texi \ + vm-i-*.i MAINTAINERCLEANFILES = c-tokenize.c diff --git a/libguile/__scm.h b/libguile/__scm.h index 3672b1c09..29b371d16 100644 --- a/libguile/__scm.h +++ b/libguile/__scm.h @@ -6,18 +6,19 @@ /* Copyright (C) 1995,1996,1998,1999,2000,2001,2002,2003, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ @@ -98,13 +99,10 @@ #define SCM_UNLIKELY(_expr) SCM_EXPECT ((_expr), 0) /* The SCM_INTERNAL macro makes it possible to explicitly declare a function - * as having "internal" linkage. */ -#if (defined __GNUC__) && \ - ((__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ == 3)) -# define SCM_INTERNAL extern __attribute__ ((__visibility__ ("internal"))) -#else -# define SCM_INTERNAL extern -#endif + * as having "internal" linkage. However our current tack on this problem is + * to use GCC 4's -fvisibility=hidden, making functions internal by default, + * and then SCM_API marks them for export. */ +#define SCM_INTERNAL extern @@ -154,13 +152,14 @@ /* SCM_API is a macro prepended to all function and data definitions - which should be exported or imported in the resulting dynamic link - library (DLL) in the Win32 port. */ + which should be exported from libguile. */ -#if defined (SCM_IMPORT) -# define SCM_API __declspec (dllimport) extern -#elif defined (SCM_EXPORT) || defined (DLL_EXPORT) -# define SCM_API __declspec (dllexport) extern +#if BUILDING_LIBGUILE && HAVE_VISIBILITY +# define SCM_API extern __attribute__((__visibility__("default"))) +#elif BUILDING_LIBGUILE && defined _MSC_VER +# define SCM_API __declspec(dllexport) extern +#elif defined _MSC_VER +# define SCM_API __declspec(dllimport) extern #else # define SCM_API extern #endif diff --git a/libguile/_scm.h b/libguile/_scm.h index e40f29bb0..627c51e03 100644 --- a/libguile/_scm.h +++ b/libguile/_scm.h @@ -3,21 +3,22 @@ #ifndef SCM__SCM_H #define SCM__SCM_H -/* Copyright (C) 1995,1996,2000,2001, 2002, 2006, 2008 Free Software Foundation, Inc. +/* Copyright (C) 1995,1996,2000,2001, 2002, 2006, 2008, 2009 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ @@ -58,6 +59,7 @@ #endif #include +#include #include "libguile/__scm.h" /* Include headers for those files central to the implementation. The @@ -78,20 +80,6 @@ #include "libguile/modules.h" #include "libguile/inline.h" -/* SCM_SYSCALL retries system calls that have been interrupted (EINTR). - However this can be avoided if the operating system can restart - system calls automatically. We assume this is the case if - sigaction is available and SA_RESTART is defined; they will be used - when installing signal handlers. - */ - -#ifdef HAVE_RESTARTABLE_SYSCALLS -#if ! SCM_USE_PTHREAD_THREADS /* However, don't assume SA_RESTART - works with pthreads... */ -#define SCM_SYSCALL(line) line -#endif -#endif - #ifndef SCM_SYSCALL #ifdef vms # ifndef __GNUC__ @@ -169,6 +157,36 @@ #define scm_from_off64_t scm_from_int64 +/* The endianness marker in objcode. */ +#ifdef WORDS_BIGENDIAN +# define SCM_OBJCODE_ENDIANNESS "BE" +#else +# define SCM_OBJCODE_ENDIANNESS "LE" +#endif + +#define _SCM_CPP_STRINGIFY(x) # x +#define SCM_CPP_STRINGIFY(x) _SCM_CPP_STRINGIFY (x) + +/* The word size marker in objcode. */ +#define SCM_OBJCODE_WORD_SIZE SCM_CPP_STRINGIFY (SIZEOF_VOID_P) + +/* Major and minor versions must be single characters. */ +#define SCM_OBJCODE_MAJOR_VERSION 0 +#define SCM_OBJCODE_MINOR_VERSION B +#define SCM_OBJCODE_MAJOR_VERSION_STRING \ + SCM_CPP_STRINGIFY(SCM_OBJCODE_MAJOR_VERSION) +#define SCM_OBJCODE_MINOR_VERSION_STRING \ + SCM_CPP_STRINGIFY(SCM_OBJCODE_MINOR_VERSION) +#define SCM_OBJCODE_VERSION_STRING \ + SCM_OBJCODE_MAJOR_VERSION_STRING "." SCM_OBJCODE_MINOR_VERSION_STRING +#define SCM_OBJCODE_MACHINE_VERSION_STRING \ + SCM_OBJCODE_VERSION_STRING "-" SCM_OBJCODE_ENDIANNESS "-" SCM_OBJCODE_WORD_SIZE + +/* The objcode magic header. */ +#define SCM_OBJCODE_COOKIE \ + "GOOF-" SCM_OBJCODE_MACHINE_VERSION_STRING "---" + + #endif /* SCM__SCM_H */ /* diff --git a/libguile/alist.c b/libguile/alist.c index ca55b082c..919bd224e 100644 --- a/libguile/alist.c +++ b/libguile/alist.c @@ -1,18 +1,19 @@ /* Copyright (C) 1995, 96, 97, 98, 99, 2000, 2001, 2004, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/alist.h b/libguile/alist.h index 76cccba2b..77c565608 100644 --- a/libguile/alist.h +++ b/libguile/alist.h @@ -6,18 +6,19 @@ /* Copyright (C) 1995,1996,2000, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/arbiters.c b/libguile/arbiters.c index a3e4d81df..3567c909e 100644 --- a/libguile/arbiters.c +++ b/libguile/arbiters.c @@ -1,18 +1,19 @@ /* Copyright (C) 1995,1996, 1997, 2000, 2001, 2004, 2005, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/arbiters.h b/libguile/arbiters.h index 7a7dfd3fa..214e92a34 100644 --- a/libguile/arbiters.h +++ b/libguile/arbiters.h @@ -6,18 +6,19 @@ /* Copyright (C) 1995,1996,2000, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/async.c b/libguile/async.c index 040082fb8..3e5a581c6 100644 --- a/libguile/async.c +++ b/libguile/async.c @@ -1,18 +1,19 @@ /* Copyright (C) 1995,1996,1997,1998,2000,2001, 2002, 2004, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ @@ -174,7 +175,7 @@ scm_async_click () SCM_DEFINE (scm_system_async, "system-async", 1, 0, 0, (SCM thunk), "This function is deprecated. You can use @var{thunk} directly\n" - "instead of explicitely creating an async object.\n") + "instead of explicitly creating an async object.\n") #define FUNC_NAME s_scm_system_async { scm_c_issue_deprecation_warning diff --git a/libguile/async.h b/libguile/async.h index c01bde031..427d9b4c8 100644 --- a/libguile/async.h +++ b/libguile/async.h @@ -6,18 +6,19 @@ /* Copyright (C) 1995,1996,1997,1998,2000,2001, 2002, 2004, 2005, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/backtrace.c b/libguile/backtrace.c index a8afcdf34..83579055f 100644 --- a/libguile/backtrace.c +++ b/libguile/backtrace.c @@ -2,18 +2,19 @@ * Copyright (C) 1996,1997,1998,1999,2000,2001, 2003, 2004, 2006 Free Software Foundation * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ #ifdef HAVE_CONFIG_H diff --git a/libguile/backtrace.h b/libguile/backtrace.h index e11cb85de..c0651667c 100644 --- a/libguile/backtrace.h +++ b/libguile/backtrace.h @@ -6,18 +6,19 @@ /* Copyright (C) 1996,1998,1999,2000,2001, 2004, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/boolean.c b/libguile/boolean.c index 4b06e04e2..d79bf7979 100644 --- a/libguile/boolean.c +++ b/libguile/boolean.c @@ -1,18 +1,19 @@ /* Copyright (C) 1995, 1996, 2000, 2001, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/boolean.h b/libguile/boolean.h index 1388c2fdc..5a8379713 100644 --- a/libguile/boolean.h +++ b/libguile/boolean.h @@ -6,18 +6,19 @@ /* Copyright (C) 1995,1996,2000, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/bytevectors.c b/libguile/bytevectors.c new file mode 100644 index 000000000..24afd2414 --- /dev/null +++ b/libguile/bytevectors.c @@ -0,0 +1,2096 @@ +/* Copyright (C) 2009 Free Software Foundation, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include + +#include "libguile/_scm.h" +#include "libguile/extensions.h" +#include "libguile/bytevectors.h" +#include "libguile/strings.h" +#include "libguile/validate.h" +#include "libguile/ieee-754.h" +#include "libguile/unif.h" +#include "libguile/srfi-4.h" + +#include +#include +#include + +#ifdef HAVE_LIMITS_H +# include +#else +/* Assuming 32-bit longs. */ +# define ULONG_MAX 4294967295UL +#endif + +#include + + + +/* Utilities. */ + +/* Convenience macros. These are used by the various templates (macros) that + are parameterized by integer signedness. */ +#define INT8_T_signed scm_t_int8 +#define INT8_T_unsigned scm_t_uint8 +#define INT16_T_signed scm_t_int16 +#define INT16_T_unsigned scm_t_uint16 +#define INT32_T_signed scm_t_int32 +#define INT32_T_unsigned scm_t_uint32 +#define is_signed_int8(_x) (((_x) >= -128L) && ((_x) <= 127L)) +#define is_unsigned_int8(_x) ((_x) <= 255UL) +#define is_signed_int16(_x) (((_x) >= -32768L) && ((_x) <= 32767L)) +#define is_unsigned_int16(_x) ((_x) <= 65535UL) +#define is_signed_int32(_x) (((_x) >= -2147483648L) && ((_x) <= 2147483647L)) +#define is_unsigned_int32(_x) ((_x) <= 4294967295UL) +#define SIGNEDNESS_signed 1 +#define SIGNEDNESS_unsigned 0 + +#define INT_TYPE(_size, _sign) INT ## _size ## _T_ ## _sign +#define INT_SWAP(_size) bswap_ ## _size +#define INT_VALID_P(_size, _sign) is_ ## _sign ## _int ## _size +#define SIGNEDNESS(_sign) SIGNEDNESS_ ## _sign + + +#define INTEGER_ACCESSOR_PROLOGUE(_len, _sign) \ + size_t c_len, c_index; \ + _sign char *c_bv; \ + \ + SCM_VALIDATE_BYTEVECTOR (1, bv); \ + c_index = scm_to_uint (index); \ + \ + c_len = SCM_BYTEVECTOR_LENGTH (bv); \ + c_bv = (_sign char *) SCM_BYTEVECTOR_CONTENTS (bv); \ + \ + if (SCM_UNLIKELY (c_index + ((_len) >> 3UL) - 1 >= c_len)) \ + scm_out_of_range (FUNC_NAME, index); + +/* Template for fixed-size integer access (only 8, 16 or 32-bit). */ +#define INTEGER_REF(_len, _sign) \ + SCM result; \ + \ + INTEGER_ACCESSOR_PROLOGUE (_len, _sign); \ + SCM_VALIDATE_SYMBOL (3, endianness); \ + \ + { \ + INT_TYPE (_len, _sign) c_result; \ + \ + memcpy (&c_result, &c_bv[c_index], (_len) / 8); \ + if (!scm_is_eq (endianness, scm_i_native_endianness)) \ + c_result = INT_SWAP (_len) (c_result); \ + \ + result = SCM_I_MAKINUM (c_result); \ + } \ + \ + return result; + +/* Template for fixed-size integer access using the native endianness. */ +#define INTEGER_NATIVE_REF(_len, _sign) \ + SCM result; \ + \ + INTEGER_ACCESSOR_PROLOGUE (_len, _sign); \ + \ + { \ + INT_TYPE (_len, _sign) c_result; \ + \ + memcpy (&c_result, &c_bv[c_index], (_len) / 8); \ + result = SCM_I_MAKINUM (c_result); \ + } \ + \ + return result; + +/* Template for fixed-size integer modification (only 8, 16 or 32-bit). */ +#define INTEGER_SET(_len, _sign) \ + INTEGER_ACCESSOR_PROLOGUE (_len, _sign); \ + SCM_VALIDATE_SYMBOL (3, endianness); \ + \ + { \ + _sign long c_value; \ + INT_TYPE (_len, _sign) c_value_short; \ + \ + if (SCM_UNLIKELY (!SCM_I_INUMP (value))) \ + scm_wrong_type_arg (FUNC_NAME, 3, value); \ + \ + c_value = SCM_I_INUM (value); \ + if (SCM_UNLIKELY (!INT_VALID_P (_len, _sign) (c_value))) \ + scm_out_of_range (FUNC_NAME, value); \ + \ + c_value_short = (INT_TYPE (_len, _sign)) c_value; \ + if (!scm_is_eq (endianness, scm_i_native_endianness)) \ + c_value_short = INT_SWAP (_len) (c_value_short); \ + \ + memcpy (&c_bv[c_index], &c_value_short, (_len) / 8); \ + } \ + \ + return SCM_UNSPECIFIED; + +/* Template for fixed-size integer modification using the native + endianness. */ +#define INTEGER_NATIVE_SET(_len, _sign) \ + INTEGER_ACCESSOR_PROLOGUE (_len, _sign); \ + \ + { \ + _sign long c_value; \ + INT_TYPE (_len, _sign) c_value_short; \ + \ + if (SCM_UNLIKELY (!SCM_I_INUMP (value))) \ + scm_wrong_type_arg (FUNC_NAME, 3, value); \ + \ + c_value = SCM_I_INUM (value); \ + if (SCM_UNLIKELY (!INT_VALID_P (_len, _sign) (c_value))) \ + scm_out_of_range (FUNC_NAME, value); \ + \ + c_value_short = (INT_TYPE (_len, _sign)) c_value; \ + \ + memcpy (&c_bv[c_index], &c_value_short, (_len) / 8); \ + } \ + \ + return SCM_UNSPECIFIED; + + + +/* Bytevector type. */ + +scm_t_bits scm_tc16_bytevector; + +#define SCM_BYTEVECTOR_SET_LENGTH(_bv, _len) \ + SCM_SET_SMOB_DATA ((_bv), (scm_t_bits) (_len)) +#define SCM_BYTEVECTOR_SET_CONTENTS(_bv, _buf) \ + SCM_SET_SMOB_DATA_2 ((_bv), (scm_t_bits) (_buf)) + +/* The empty bytevector. */ +SCM scm_null_bytevector = SCM_UNSPECIFIED; + + +static inline SCM +make_bytevector_from_buffer (size_t len, signed char *contents) +{ + /* Assuming LEN > SCM_BYTEVECTOR_INLINE_THRESHOLD. */ + SCM_RETURN_NEWSMOB2 (scm_tc16_bytevector, len, contents); +} + +static inline SCM +make_bytevector (size_t len) +{ + SCM bv; + + if (SCM_UNLIKELY (len == 0)) + bv = scm_null_bytevector; + else + { + signed char *contents = NULL; + + if (!SCM_BYTEVECTOR_INLINEABLE_SIZE_P (len)) + contents = (signed char *) scm_gc_malloc (len, SCM_GC_BYTEVECTOR); + + bv = make_bytevector_from_buffer (len, contents); + } + + return bv; +} + +/* Return a new bytevector of size LEN octets. */ +SCM +scm_c_make_bytevector (size_t len) +{ + return (make_bytevector (len)); +} + +/* Return a bytevector of size LEN made up of CONTENTS. The area pointed to + by CONTENTS must have been allocated using `scm_gc_malloc ()'. */ +SCM +scm_c_take_bytevector (signed char *contents, size_t len) +{ + SCM bv; + + if (SCM_UNLIKELY (SCM_BYTEVECTOR_INLINEABLE_SIZE_P (len))) + { + /* Copy CONTENTS into an "in-line" buffer, then free CONTENTS. */ + signed char *c_bv; + + bv = make_bytevector (len); + c_bv = SCM_BYTEVECTOR_CONTENTS (bv); + memcpy (c_bv, contents, len); + scm_gc_free (contents, len, SCM_GC_BYTEVECTOR); + } + else + bv = make_bytevector_from_buffer (len, contents); + + return bv; +} + +/* Shrink BV to C_NEW_LEN (which is assumed to be smaller than its current + size) and return BV. */ +SCM +scm_i_shrink_bytevector (SCM bv, size_t c_new_len) +{ + if (!SCM_BYTEVECTOR_INLINE_P (bv)) + { + size_t c_len; + signed char *c_bv, *c_new_bv; + + c_len = SCM_BYTEVECTOR_LENGTH (bv); + c_bv = SCM_BYTEVECTOR_CONTENTS (bv); + + SCM_BYTEVECTOR_SET_LENGTH (bv, c_new_len); + + if (SCM_BYTEVECTOR_INLINEABLE_SIZE_P (c_new_len)) + { + /* Copy to the in-line buffer and free the current buffer. */ + c_new_bv = SCM_BYTEVECTOR_CONTENTS (bv); + memcpy (c_new_bv, c_bv, c_new_len); + scm_gc_free (c_bv, c_len, SCM_GC_BYTEVECTOR); + } + else + { + /* Resize the existing buffer. */ + c_new_bv = scm_gc_realloc (c_bv, c_len, c_new_len, + SCM_GC_BYTEVECTOR); + SCM_BYTEVECTOR_SET_CONTENTS (bv, c_new_bv); + } + } + + return bv; +} + +int +scm_is_bytevector (SCM obj) +{ + return SCM_SMOB_PREDICATE (scm_tc16_bytevector, obj); +} + +size_t +scm_c_bytevector_length (SCM bv) +#define FUNC_NAME "scm_c_bytevector_length" +{ + SCM_VALIDATE_BYTEVECTOR (1, bv); + + return SCM_BYTEVECTOR_LENGTH (bv); +} +#undef FUNC_NAME + +scm_t_uint8 +scm_c_bytevector_ref (SCM bv, size_t index) +#define FUNC_NAME "scm_c_bytevector_ref" +{ + size_t c_len; + const scm_t_uint8 *c_bv; + + SCM_VALIDATE_BYTEVECTOR (1, bv); + + c_len = SCM_BYTEVECTOR_LENGTH (bv); + c_bv = (scm_t_uint8 *) SCM_BYTEVECTOR_CONTENTS (bv); + + if (SCM_UNLIKELY (index >= c_len)) + scm_out_of_range (FUNC_NAME, scm_from_size_t (index)); + + return c_bv[index]; +} +#undef FUNC_NAME + +void +scm_c_bytevector_set_x (SCM bv, size_t index, scm_t_uint8 value) +#define FUNC_NAME "scm_c_bytevector_set_x" +{ + size_t c_len; + scm_t_uint8 *c_bv; + + SCM_VALIDATE_BYTEVECTOR (1, bv); + + c_len = SCM_BYTEVECTOR_LENGTH (bv); + c_bv = (scm_t_uint8 *) SCM_BYTEVECTOR_CONTENTS (bv); + + if (SCM_UNLIKELY (index >= c_len)) + scm_out_of_range (FUNC_NAME, scm_from_size_t (index)); + + c_bv[index] = value; +} +#undef FUNC_NAME + +/* This procedure is used by `scm_c_generalized_vector_set_x ()'. */ +void +scm_i_bytevector_generalized_set_x (SCM bv, size_t index, SCM value) +#define FUNC_NAME "scm_i_bytevector_generalized_set_x" +{ + scm_c_bytevector_set_x (bv, index, scm_to_uint8 (value)); +} +#undef FUNC_NAME + +static int +print_bytevector (SCM bv, SCM port, scm_print_state *pstate) +{ + unsigned c_len, i; + unsigned char *c_bv; + + c_len = SCM_BYTEVECTOR_LENGTH (bv); + c_bv = (unsigned char *) SCM_BYTEVECTOR_CONTENTS (bv); + + scm_puts ("#vu8(", port); + for (i = 0; i < c_len; i++) + { + if (i > 0) + scm_putc (' ', port); + + scm_uintprint (c_bv[i], 10, port); + } + + scm_putc (')', port); + + /* Make GCC think we use it. */ + scm_remember_upto_here ((SCM) pstate); + + return 1; +} + +static SCM +bytevector_equal_p (SCM bv1, SCM bv2) +{ + return scm_bytevector_eq_p (bv1, bv2); +} + +static size_t +free_bytevector (SCM bv) +{ + + if (!SCM_BYTEVECTOR_INLINE_P (bv)) + { + unsigned c_len; + signed char *c_bv; + + c_bv = SCM_BYTEVECTOR_CONTENTS (bv); + c_len = SCM_BYTEVECTOR_LENGTH (bv); + + scm_gc_free (c_bv, c_len, SCM_GC_BYTEVECTOR); + } + + return 0; +} + + + +/* General operations. */ + +SCM_SYMBOL (scm_sym_big, "big"); +SCM_SYMBOL (scm_sym_little, "little"); + +SCM scm_endianness_big, scm_endianness_little; + +/* Host endianness (a symbol). */ +SCM scm_i_native_endianness = SCM_UNSPECIFIED; + +/* Byte-swapping. */ +#ifndef bswap_24 +# define bswap_24(_x) \ + ((((_x) & 0xff0000) >> 16) | \ + (((_x) & 0x00ff00)) | \ + (((_x) & 0x0000ff) << 16)) +#endif + + +SCM_DEFINE (scm_native_endianness, "native-endianness", 0, 0, 0, + (void), + "Return a symbol denoting the machine's native endianness.") +#define FUNC_NAME s_scm_native_endianness +{ + return scm_i_native_endianness; +} +#undef FUNC_NAME + +SCM_DEFINE (scm_bytevector_p, "bytevector?", 1, 0, 0, + (SCM obj), + "Return true if @var{obj} is a bytevector.") +#define FUNC_NAME s_scm_bytevector_p +{ + return scm_from_bool (scm_is_bytevector (obj)); +} +#undef FUNC_NAME + +SCM_DEFINE (scm_make_bytevector, "make-bytevector", 1, 1, 0, + (SCM len, SCM fill), + "Return a newly allocated bytevector of @var{len} bytes, " + "optionally filled with @var{fill}.") +#define FUNC_NAME s_scm_make_bytevector +{ + SCM bv; + unsigned c_len; + signed char c_fill = '\0'; + + SCM_VALIDATE_UINT_COPY (1, len, c_len); + if (fill != SCM_UNDEFINED) + { + int value; + + value = scm_to_int (fill); + if (SCM_UNLIKELY ((value < -128) || (value > 255))) + scm_out_of_range (FUNC_NAME, fill); + c_fill = (signed char) value; + } + + bv = make_bytevector (c_len); + if (fill != SCM_UNDEFINED) + { + unsigned i; + signed char *contents; + + contents = SCM_BYTEVECTOR_CONTENTS (bv); + for (i = 0; i < c_len; i++) + contents[i] = c_fill; + } + + return bv; +} +#undef FUNC_NAME + +SCM_DEFINE (scm_bytevector_length, "bytevector-length", 1, 0, 0, + (SCM bv), + "Return the length (in bytes) of @var{bv}.") +#define FUNC_NAME s_scm_bytevector_length +{ + return scm_from_uint (scm_c_bytevector_length (bv)); +} +#undef FUNC_NAME + +SCM_DEFINE (scm_bytevector_eq_p, "bytevector=?", 2, 0, 0, + (SCM bv1, SCM bv2), + "Return is @var{bv1} equals to @var{bv2}---i.e., if they " + "have the same length and contents.") +#define FUNC_NAME s_scm_bytevector_eq_p +{ + SCM result = SCM_BOOL_F; + unsigned c_len1, c_len2; + + SCM_VALIDATE_BYTEVECTOR (1, bv1); + SCM_VALIDATE_BYTEVECTOR (2, bv2); + + c_len1 = SCM_BYTEVECTOR_LENGTH (bv1); + c_len2 = SCM_BYTEVECTOR_LENGTH (bv2); + + if (c_len1 == c_len2) + { + signed char *c_bv1, *c_bv2; + + c_bv1 = SCM_BYTEVECTOR_CONTENTS (bv1); + c_bv2 = SCM_BYTEVECTOR_CONTENTS (bv2); + + result = scm_from_bool (!memcmp (c_bv1, c_bv2, c_len1)); + } + + return result; +} +#undef FUNC_NAME + +SCM_DEFINE (scm_bytevector_fill_x, "bytevector-fill!", 2, 0, 0, + (SCM bv, SCM fill), + "Fill bytevector @var{bv} with @var{fill}, a byte.") +#define FUNC_NAME s_scm_bytevector_fill_x +{ + unsigned c_len, i; + signed char *c_bv, c_fill; + + SCM_VALIDATE_BYTEVECTOR (1, bv); + c_fill = scm_to_int8 (fill); + + c_len = SCM_BYTEVECTOR_LENGTH (bv); + c_bv = SCM_BYTEVECTOR_CONTENTS (bv); + + for (i = 0; i < c_len; i++) + c_bv[i] = c_fill; + + return SCM_UNSPECIFIED; +} +#undef FUNC_NAME + +SCM_DEFINE (scm_bytevector_copy_x, "bytevector-copy!", 5, 0, 0, + (SCM source, SCM source_start, SCM target, SCM target_start, + SCM len), + "Copy @var{len} bytes from @var{source} into @var{target}, " + "starting reading from @var{source_start} (a positive index " + "within @var{source}) and start writing at " + "@var{target_start}.") +#define FUNC_NAME s_scm_bytevector_copy_x +{ + unsigned c_len, c_source_len, c_target_len; + unsigned c_source_start, c_target_start; + signed char *c_source, *c_target; + + SCM_VALIDATE_BYTEVECTOR (1, source); + SCM_VALIDATE_BYTEVECTOR (3, target); + + c_len = scm_to_uint (len); + c_source_start = scm_to_uint (source_start); + c_target_start = scm_to_uint (target_start); + + c_source = SCM_BYTEVECTOR_CONTENTS (source); + c_target = SCM_BYTEVECTOR_CONTENTS (target); + c_source_len = SCM_BYTEVECTOR_LENGTH (source); + c_target_len = SCM_BYTEVECTOR_LENGTH (target); + + if (SCM_UNLIKELY (c_source_start + c_len > c_source_len)) + scm_out_of_range (FUNC_NAME, source_start); + if (SCM_UNLIKELY (c_target_start + c_len > c_target_len)) + scm_out_of_range (FUNC_NAME, target_start); + + memcpy (c_target + c_target_start, + c_source + c_source_start, + c_len); + + return SCM_UNSPECIFIED; +} +#undef FUNC_NAME + +SCM_DEFINE (scm_bytevector_copy, "bytevector-copy", 1, 0, 0, + (SCM bv), + "Return a newly allocated copy of @var{bv}.") +#define FUNC_NAME s_scm_bytevector_copy +{ + SCM copy; + unsigned c_len; + signed char *c_bv, *c_copy; + + SCM_VALIDATE_BYTEVECTOR (1, bv); + + c_len = SCM_BYTEVECTOR_LENGTH (bv); + c_bv = SCM_BYTEVECTOR_CONTENTS (bv); + + copy = make_bytevector (c_len); + c_copy = SCM_BYTEVECTOR_CONTENTS (copy); + memcpy (c_copy, c_bv, c_len); + + return copy; +} +#undef FUNC_NAME + +SCM_DEFINE (scm_uniform_array_to_bytevector, "uniform-array->bytevector", + 1, 0, 0, (SCM array), + "Return a newly allocated bytevector whose contents\n" + "will be copied from the uniform array @var{array}.") +#define FUNC_NAME s_scm_uniform_array_to_bytevector +{ + SCM contents, ret; + size_t len; + scm_t_array_handle h; + const void *base; + size_t sz; + + contents = scm_array_contents (array, SCM_BOOL_T); + if (scm_is_false (contents)) + scm_wrong_type_arg_msg (FUNC_NAME, 0, array, "uniform contiguous array"); + + scm_array_get_handle (contents, &h); + + base = scm_array_handle_uniform_elements (&h); + len = h.dims->inc * (h.dims->ubnd - h.dims->lbnd + 1); + sz = scm_array_handle_uniform_element_size (&h); + + ret = make_bytevector (len * sz); + memcpy (SCM_BYTEVECTOR_CONTENTS (ret), base, len * sz); + + scm_array_handle_release (&h); + + return ret; +} +#undef FUNC_NAME + + +/* Operations on bytes and octets. */ + +SCM_DEFINE (scm_bytevector_u8_ref, "bytevector-u8-ref", 2, 0, 0, + (SCM bv, SCM index), + "Return the octet located at @var{index} in @var{bv}.") +#define FUNC_NAME s_scm_bytevector_u8_ref +{ + INTEGER_NATIVE_REF (8, unsigned); +} +#undef FUNC_NAME + +SCM_DEFINE (scm_bytevector_s8_ref, "bytevector-s8-ref", 2, 0, 0, + (SCM bv, SCM index), + "Return the byte located at @var{index} in @var{bv}.") +#define FUNC_NAME s_scm_bytevector_s8_ref +{ + INTEGER_NATIVE_REF (8, signed); +} +#undef FUNC_NAME + +SCM_DEFINE (scm_bytevector_u8_set_x, "bytevector-u8-set!", 3, 0, 0, + (SCM bv, SCM index, SCM value), + "Return the octet located at @var{index} in @var{bv}.") +#define FUNC_NAME s_scm_bytevector_u8_set_x +{ + INTEGER_NATIVE_SET (8, unsigned); +} +#undef FUNC_NAME + +SCM_DEFINE (scm_bytevector_s8_set_x, "bytevector-s8-set!", 3, 0, 0, + (SCM bv, SCM index, SCM value), + "Return the octet located at @var{index} in @var{bv}.") +#define FUNC_NAME s_scm_bytevector_s8_set_x +{ + INTEGER_NATIVE_SET (8, signed); +} +#undef FUNC_NAME + +#undef OCTET_ACCESSOR_PROLOGUE + + +SCM_DEFINE (scm_bytevector_to_u8_list, "bytevector->u8-list", 1, 0, 0, + (SCM bv), + "Return a newly allocated list of octets containing the " + "contents of @var{bv}.") +#define FUNC_NAME s_scm_bytevector_to_u8_list +{ + SCM lst, pair; + unsigned c_len, i; + unsigned char *c_bv; + + SCM_VALIDATE_BYTEVECTOR (1, bv); + + c_len = SCM_BYTEVECTOR_LENGTH (bv); + c_bv = (unsigned char *) SCM_BYTEVECTOR_CONTENTS (bv); + + lst = scm_make_list (scm_from_uint (c_len), SCM_UNSPECIFIED); + for (i = 0, pair = lst; + i < c_len; + i++, pair = SCM_CDR (pair)) + { + SCM_SETCAR (pair, SCM_I_MAKINUM (c_bv[i])); + } + + return lst; +} +#undef FUNC_NAME + +SCM_DEFINE (scm_u8_list_to_bytevector, "u8-list->bytevector", 1, 0, 0, + (SCM lst), + "Turn @var{lst}, a list of octets, into a bytevector.") +#define FUNC_NAME s_scm_u8_list_to_bytevector +{ + SCM bv, item; + long c_len, i; + unsigned char *c_bv; + + SCM_VALIDATE_LIST_COPYLEN (1, lst, c_len); + + bv = make_bytevector (c_len); + c_bv = (unsigned char *) SCM_BYTEVECTOR_CONTENTS (bv); + + for (i = 0; i < c_len; lst = SCM_CDR (lst), i++) + { + item = SCM_CAR (lst); + + if (SCM_LIKELY (SCM_I_INUMP (item))) + { + long c_item; + + c_item = SCM_I_INUM (item); + if (SCM_LIKELY ((c_item >= 0) && (c_item < 256))) + c_bv[i] = (unsigned char) c_item; + else + goto type_error; + } + else + goto type_error; + } + + return bv; + + type_error: + scm_wrong_type_arg (FUNC_NAME, 1, item); + + return SCM_BOOL_F; +} +#undef FUNC_NAME + +/* Compute the two's complement of VALUE (a positive integer) on SIZE octets + using (2^(SIZE * 8) - VALUE). */ +static inline void +twos_complement (mpz_t value, size_t size) +{ + unsigned long bit_count; + + /* We expect BIT_COUNT to fit in a unsigned long thanks to the range + checking on SIZE performed earlier. */ + bit_count = (unsigned long) size << 3UL; + + if (SCM_LIKELY (bit_count < sizeof (unsigned long))) + mpz_ui_sub (value, 1UL << bit_count, value); + else + { + mpz_t max; + + mpz_init (max); + mpz_ui_pow_ui (max, 2, bit_count); + mpz_sub (value, max, value); + mpz_clear (max); + } +} + +static inline SCM +bytevector_large_ref (const char *c_bv, size_t c_size, int signed_p, + SCM endianness) +{ + SCM result; + mpz_t c_mpz; + int c_endianness, negative_p = 0; + + if (signed_p) + { + if (scm_is_eq (endianness, scm_sym_big)) + negative_p = c_bv[0] & 0x80; + else + negative_p = c_bv[c_size - 1] & 0x80; + } + + c_endianness = scm_is_eq (endianness, scm_sym_big) ? 1 : -1; + + mpz_init (c_mpz); + mpz_import (c_mpz, 1 /* 1 word */, 1 /* word order doesn't matter */, + c_size /* word is C_SIZE-byte long */, + c_endianness, + 0 /* nails */, c_bv); + + if (signed_p && negative_p) + { + twos_complement (c_mpz, c_size); + mpz_neg (c_mpz, c_mpz); + } + + result = scm_from_mpz (c_mpz); + mpz_clear (c_mpz); /* FIXME: Needed? */ + + return result; +} + +static inline int +bytevector_large_set (char *c_bv, size_t c_size, int signed_p, + SCM value, SCM endianness) +{ + mpz_t c_mpz; + int c_endianness, c_sign, err = 0; + + c_endianness = scm_is_eq (endianness, scm_sym_big) ? 1 : -1; + + mpz_init (c_mpz); + scm_to_mpz (value, c_mpz); + + c_sign = mpz_sgn (c_mpz); + if (c_sign < 0) + { + if (SCM_LIKELY (signed_p)) + { + mpz_neg (c_mpz, c_mpz); + twos_complement (c_mpz, c_size); + } + else + { + err = -1; + goto finish; + } + } + + if (c_sign == 0) + /* Zero. */ + memset (c_bv, 0, c_size); + else + { + size_t word_count, value_size; + + value_size = (mpz_sizeinbase (c_mpz, 2) + (8 * c_size)) / (8 * c_size); + if (SCM_UNLIKELY (value_size > c_size)) + { + err = -2; + goto finish; + } + + + mpz_export (c_bv, &word_count, 1 /* word order doesn't matter */, + c_size, c_endianness, + 0 /* nails */, c_mpz); + if (SCM_UNLIKELY (word_count != 1)) + /* Shouldn't happen since we already checked with VALUE_SIZE. */ + abort (); + } + + finish: + mpz_clear (c_mpz); + + return err; +} + +#define GENERIC_INTEGER_ACCESSOR_PROLOGUE(_sign) \ + unsigned long c_len, c_index, c_size; \ + char *c_bv; \ + \ + SCM_VALIDATE_BYTEVECTOR (1, bv); \ + c_index = scm_to_ulong (index); \ + c_size = scm_to_ulong (size); \ + \ + c_len = SCM_BYTEVECTOR_LENGTH (bv); \ + c_bv = (char *) SCM_BYTEVECTOR_CONTENTS (bv); \ + \ + /* C_SIZE must have its 3 higher bits set to zero so that \ + multiplying it by 8 yields a number that fits in an \ + unsigned long. */ \ + if (SCM_UNLIKELY ((c_size == 0) || (c_size >= (ULONG_MAX >> 3L)))) \ + scm_out_of_range (FUNC_NAME, size); \ + if (SCM_UNLIKELY (c_index + c_size > c_len)) \ + scm_out_of_range (FUNC_NAME, index); + + +/* Template of an integer reference function. */ +#define GENERIC_INTEGER_REF(_sign) \ + SCM result; \ + \ + if (c_size < 3) \ + { \ + int swap; \ + _sign int value; \ + \ + swap = !scm_is_eq (endianness, scm_i_native_endianness); \ + switch (c_size) \ + { \ + case 1: \ + { \ + _sign char c_value8; \ + memcpy (&c_value8, c_bv, 1); \ + value = c_value8; \ + } \ + break; \ + case 2: \ + { \ + INT_TYPE (16, _sign) c_value16; \ + memcpy (&c_value16, c_bv, 2); \ + if (swap) \ + value = (INT_TYPE (16, _sign)) bswap_16 (c_value16); \ + else \ + value = c_value16; \ + } \ + break; \ + default: \ + abort (); \ + } \ + \ + result = SCM_I_MAKINUM ((_sign int) value); \ + } \ + else \ + result = bytevector_large_ref ((char *) c_bv, \ + c_size, SIGNEDNESS (_sign), \ + endianness); \ + \ + return result; + +static inline SCM +bytevector_signed_ref (const char *c_bv, size_t c_size, SCM endianness) +{ + GENERIC_INTEGER_REF (signed); +} + +static inline SCM +bytevector_unsigned_ref (const char *c_bv, size_t c_size, SCM endianness) +{ + GENERIC_INTEGER_REF (unsigned); +} + + +/* Template of an integer assignment function. */ +#define GENERIC_INTEGER_SET(_sign) \ + if (c_size < 3) \ + { \ + _sign int c_value; \ + \ + if (SCM_UNLIKELY (!SCM_I_INUMP (value))) \ + goto range_error; \ + \ + c_value = SCM_I_INUM (value); \ + switch (c_size) \ + { \ + case 1: \ + if (SCM_LIKELY (INT_VALID_P (8, _sign) (c_value))) \ + { \ + _sign char c_value8; \ + c_value8 = (_sign char) c_value; \ + memcpy (c_bv, &c_value8, 1); \ + } \ + else \ + goto range_error; \ + break; \ + \ + case 2: \ + if (SCM_LIKELY (INT_VALID_P (16, _sign) (c_value))) \ + { \ + int swap; \ + INT_TYPE (16, _sign) c_value16; \ + \ + swap = !scm_is_eq (endianness, scm_i_native_endianness); \ + \ + if (swap) \ + c_value16 = (INT_TYPE (16, _sign)) bswap_16 (c_value); \ + else \ + c_value16 = c_value; \ + \ + memcpy (c_bv, &c_value16, 2); \ + } \ + else \ + goto range_error; \ + break; \ + \ + default: \ + abort (); \ + } \ + } \ + else \ + { \ + int err; \ + \ + err = bytevector_large_set (c_bv, c_size, \ + SIGNEDNESS (_sign), \ + value, endianness); \ + if (err) \ + goto range_error; \ + } \ + \ + return; \ + \ + range_error: \ + scm_out_of_range (FUNC_NAME, value); \ + return; + +static inline void +bytevector_signed_set (char *c_bv, size_t c_size, + SCM value, SCM endianness, + const char *func_name) +#define FUNC_NAME func_name +{ + GENERIC_INTEGER_SET (signed); +} +#undef FUNC_NAME + +static inline void +bytevector_unsigned_set (char *c_bv, size_t c_size, + SCM value, SCM endianness, + const char *func_name) +#define FUNC_NAME func_name +{ + GENERIC_INTEGER_SET (unsigned); +} +#undef FUNC_NAME + +#undef GENERIC_INTEGER_SET +#undef GENERIC_INTEGER_REF + + +SCM_DEFINE (scm_bytevector_uint_ref, "bytevector-uint-ref", 4, 0, 0, + (SCM bv, SCM index, SCM endianness, SCM size), + "Return the @var{size}-octet long unsigned integer at index " + "@var{index} in @var{bv}.") +#define FUNC_NAME s_scm_bytevector_uint_ref +{ + GENERIC_INTEGER_ACCESSOR_PROLOGUE (unsigned); + + return (bytevector_unsigned_ref (&c_bv[c_index], c_size, endianness)); +} +#undef FUNC_NAME + +SCM_DEFINE (scm_bytevector_sint_ref, "bytevector-sint-ref", 4, 0, 0, + (SCM bv, SCM index, SCM endianness, SCM size), + "Return the @var{size}-octet long unsigned integer at index " + "@var{index} in @var{bv}.") +#define FUNC_NAME s_scm_bytevector_sint_ref +{ + GENERIC_INTEGER_ACCESSOR_PROLOGUE (signed); + + return (bytevector_signed_ref (&c_bv[c_index], c_size, endianness)); +} +#undef FUNC_NAME + +SCM_DEFINE (scm_bytevector_uint_set_x, "bytevector-uint-set!", 5, 0, 0, + (SCM bv, SCM index, SCM value, SCM endianness, SCM size), + "Set the @var{size}-octet long unsigned integer at @var{index} " + "to @var{value}.") +#define FUNC_NAME s_scm_bytevector_uint_set_x +{ + GENERIC_INTEGER_ACCESSOR_PROLOGUE (unsigned); + + bytevector_unsigned_set (&c_bv[c_index], c_size, value, endianness, + FUNC_NAME); + + return SCM_UNSPECIFIED; +} +#undef FUNC_NAME + +SCM_DEFINE (scm_bytevector_sint_set_x, "bytevector-sint-set!", 5, 0, 0, + (SCM bv, SCM index, SCM value, SCM endianness, SCM size), + "Set the @var{size}-octet long signed integer at @var{index} " + "to @var{value}.") +#define FUNC_NAME s_scm_bytevector_sint_set_x +{ + GENERIC_INTEGER_ACCESSOR_PROLOGUE (signed); + + bytevector_signed_set (&c_bv[c_index], c_size, value, endianness, + FUNC_NAME); + + return SCM_UNSPECIFIED; +} +#undef FUNC_NAME + + + +/* Operations on integers of arbitrary size. */ + +#define INTEGERS_TO_LIST(_sign) \ + SCM lst, pair; \ + size_t i, c_len, c_size; \ + \ + SCM_VALIDATE_BYTEVECTOR (1, bv); \ + SCM_VALIDATE_SYMBOL (2, endianness); \ + c_size = scm_to_uint (size); \ + \ + c_len = SCM_BYTEVECTOR_LENGTH (bv); \ + if (SCM_UNLIKELY (c_len == 0)) \ + lst = SCM_EOL; \ + else if (SCM_UNLIKELY (c_len < c_size)) \ + scm_out_of_range (FUNC_NAME, size); \ + else \ + { \ + const char *c_bv; \ + \ + c_bv = (char *) SCM_BYTEVECTOR_CONTENTS (bv); \ + \ + lst = scm_make_list (scm_from_uint (c_len / c_size), \ + SCM_UNSPECIFIED); \ + for (i = 0, pair = lst; \ + i <= c_len - c_size; \ + i += c_size, c_bv += c_size, pair = SCM_CDR (pair)) \ + { \ + SCM_SETCAR (pair, \ + bytevector_ ## _sign ## _ref (c_bv, c_size, \ + endianness)); \ + } \ + } \ + \ + return lst; + +SCM_DEFINE (scm_bytevector_to_sint_list, "bytevector->sint-list", + 3, 0, 0, + (SCM bv, SCM endianness, SCM size), + "Return a list of signed integers of @var{size} octets " + "representing the contents of @var{bv}.") +#define FUNC_NAME s_scm_bytevector_to_sint_list +{ + INTEGERS_TO_LIST (signed); +} +#undef FUNC_NAME + +SCM_DEFINE (scm_bytevector_to_uint_list, "bytevector->uint-list", + 3, 0, 0, + (SCM bv, SCM endianness, SCM size), + "Return a list of unsigned integers of @var{size} octets " + "representing the contents of @var{bv}.") +#define FUNC_NAME s_scm_bytevector_to_uint_list +{ + INTEGERS_TO_LIST (unsigned); +} +#undef FUNC_NAME + +#undef INTEGER_TO_LIST + + +#define INTEGER_LIST_TO_BYTEVECTOR(_sign) \ + SCM bv; \ + long c_len; \ + size_t c_size; \ + char *c_bv, *c_bv_ptr; \ + \ + SCM_VALIDATE_LIST_COPYLEN (1, lst, c_len); \ + SCM_VALIDATE_SYMBOL (2, endianness); \ + c_size = scm_to_uint (size); \ + \ + if (SCM_UNLIKELY ((c_size == 0) || (c_size >= (ULONG_MAX >> 3L)))) \ + scm_out_of_range (FUNC_NAME, size); \ + \ + bv = make_bytevector (c_len * c_size); \ + c_bv = (char *) SCM_BYTEVECTOR_CONTENTS (bv); \ + \ + for (c_bv_ptr = c_bv; \ + !scm_is_null (lst); \ + lst = SCM_CDR (lst), c_bv_ptr += c_size) \ + { \ + bytevector_ ## _sign ## _set (c_bv_ptr, c_size, \ + SCM_CAR (lst), endianness, \ + FUNC_NAME); \ + } \ + \ + return bv; + + +SCM_DEFINE (scm_uint_list_to_bytevector, "uint-list->bytevector", + 3, 0, 0, + (SCM lst, SCM endianness, SCM size), + "Return a bytevector containing the unsigned integers " + "listed in @var{lst} and encoded on @var{size} octets " + "according to @var{endianness}.") +#define FUNC_NAME s_scm_uint_list_to_bytevector +{ + INTEGER_LIST_TO_BYTEVECTOR (unsigned); +} +#undef FUNC_NAME + +SCM_DEFINE (scm_sint_list_to_bytevector, "sint-list->bytevector", + 3, 0, 0, + (SCM lst, SCM endianness, SCM size), + "Return a bytevector containing the signed integers " + "listed in @var{lst} and encoded on @var{size} octets " + "according to @var{endianness}.") +#define FUNC_NAME s_scm_sint_list_to_bytevector +{ + INTEGER_LIST_TO_BYTEVECTOR (signed); +} +#undef FUNC_NAME + +#undef INTEGER_LIST_TO_BYTEVECTOR + + + +/* Operations on 16-bit integers. */ + +SCM_DEFINE (scm_bytevector_u16_ref, "bytevector-u16-ref", + 3, 0, 0, + (SCM bv, SCM index, SCM endianness), + "Return the unsigned 16-bit integer from @var{bv} at " + "@var{index}.") +#define FUNC_NAME s_scm_bytevector_u16_ref +{ + INTEGER_REF (16, unsigned); +} +#undef FUNC_NAME + +SCM_DEFINE (scm_bytevector_s16_ref, "bytevector-s16-ref", + 3, 0, 0, + (SCM bv, SCM index, SCM endianness), + "Return the signed 16-bit integer from @var{bv} at " + "@var{index}.") +#define FUNC_NAME s_scm_bytevector_s16_ref +{ + INTEGER_REF (16, signed); +} +#undef FUNC_NAME + +SCM_DEFINE (scm_bytevector_u16_native_ref, "bytevector-u16-native-ref", + 2, 0, 0, + (SCM bv, SCM index), + "Return the unsigned 16-bit integer from @var{bv} at " + "@var{index} using the native endianness.") +#define FUNC_NAME s_scm_bytevector_u16_native_ref +{ + INTEGER_NATIVE_REF (16, unsigned); +} +#undef FUNC_NAME + +SCM_DEFINE (scm_bytevector_s16_native_ref, "bytevector-s16-native-ref", + 2, 0, 0, + (SCM bv, SCM index), + "Return the unsigned 16-bit integer from @var{bv} at " + "@var{index} using the native endianness.") +#define FUNC_NAME s_scm_bytevector_s16_native_ref +{ + INTEGER_NATIVE_REF (16, signed); +} +#undef FUNC_NAME + +SCM_DEFINE (scm_bytevector_u16_set_x, "bytevector-u16-set!", + 4, 0, 0, + (SCM bv, SCM index, SCM value, SCM endianness), + "Store @var{value} in @var{bv} at @var{index} according to " + "@var{endianness}.") +#define FUNC_NAME s_scm_bytevector_u16_set_x +{ + INTEGER_SET (16, unsigned); +} +#undef FUNC_NAME + +SCM_DEFINE (scm_bytevector_s16_set_x, "bytevector-s16-set!", + 4, 0, 0, + (SCM bv, SCM index, SCM value, SCM endianness), + "Store @var{value} in @var{bv} at @var{index} according to " + "@var{endianness}.") +#define FUNC_NAME s_scm_bytevector_s16_set_x +{ + INTEGER_SET (16, signed); +} +#undef FUNC_NAME + +SCM_DEFINE (scm_bytevector_u16_native_set_x, "bytevector-u16-native-set!", + 3, 0, 0, + (SCM bv, SCM index, SCM value), + "Store the unsigned integer @var{value} at index @var{index} " + "of @var{bv} using the native endianness.") +#define FUNC_NAME s_scm_bytevector_u16_native_set_x +{ + INTEGER_NATIVE_SET (16, unsigned); +} +#undef FUNC_NAME + +SCM_DEFINE (scm_bytevector_s16_native_set_x, "bytevector-s16-native-set!", + 3, 0, 0, + (SCM bv, SCM index, SCM value), + "Store the signed integer @var{value} at index @var{index} " + "of @var{bv} using the native endianness.") +#define FUNC_NAME s_scm_bytevector_s16_native_set_x +{ + INTEGER_NATIVE_SET (16, signed); +} +#undef FUNC_NAME + + + +/* Operations on 32-bit integers. */ + +/* Unfortunately, on 32-bit machines `SCM' is not large enough to hold + arbitrary 32-bit integers. Thus we fall back to using the + `large_{ref,set}' variants on 32-bit machines. */ + +#define LARGE_INTEGER_REF(_len, _sign) \ + INTEGER_ACCESSOR_PROLOGUE(_len, _sign); \ + SCM_VALIDATE_SYMBOL (3, endianness); \ + \ + return (bytevector_large_ref ((char *) c_bv + c_index, _len / 8, \ + SIGNEDNESS (_sign), endianness)); + +#define LARGE_INTEGER_SET(_len, _sign) \ + int err; \ + INTEGER_ACCESSOR_PROLOGUE (_len, _sign); \ + SCM_VALIDATE_SYMBOL (4, endianness); \ + \ + err = bytevector_large_set ((char *) c_bv + c_index, _len / 8, \ + SIGNEDNESS (_sign), value, endianness); \ + if (SCM_UNLIKELY (err)) \ + scm_out_of_range (FUNC_NAME, value); \ + \ + return SCM_UNSPECIFIED; + +#define LARGE_INTEGER_NATIVE_REF(_len, _sign) \ + INTEGER_ACCESSOR_PROLOGUE(_len, _sign); \ + return (bytevector_large_ref ((char *) c_bv + c_index, _len / 8, \ + SIGNEDNESS (_sign), scm_i_native_endianness)); + +#define LARGE_INTEGER_NATIVE_SET(_len, _sign) \ + int err; \ + INTEGER_ACCESSOR_PROLOGUE (_len, _sign); \ + \ + err = bytevector_large_set ((char *) c_bv + c_index, _len / 8, \ + SIGNEDNESS (_sign), value, \ + scm_i_native_endianness); \ + if (SCM_UNLIKELY (err)) \ + scm_out_of_range (FUNC_NAME, value); \ + \ + return SCM_UNSPECIFIED; + + +SCM_DEFINE (scm_bytevector_u32_ref, "bytevector-u32-ref", + 3, 0, 0, + (SCM bv, SCM index, SCM endianness), + "Return the unsigned 32-bit integer from @var{bv} at " + "@var{index}.") +#define FUNC_NAME s_scm_bytevector_u32_ref +{ +#if SIZEOF_VOID_P > 4 + INTEGER_REF (32, unsigned); +#else + LARGE_INTEGER_REF (32, unsigned); +#endif +} +#undef FUNC_NAME + +SCM_DEFINE (scm_bytevector_s32_ref, "bytevector-s32-ref", + 3, 0, 0, + (SCM bv, SCM index, SCM endianness), + "Return the signed 32-bit integer from @var{bv} at " + "@var{index}.") +#define FUNC_NAME s_scm_bytevector_s32_ref +{ +#if SIZEOF_VOID_P > 4 + INTEGER_REF (32, signed); +#else + LARGE_INTEGER_REF (32, signed); +#endif +} +#undef FUNC_NAME + +SCM_DEFINE (scm_bytevector_u32_native_ref, "bytevector-u32-native-ref", + 2, 0, 0, + (SCM bv, SCM index), + "Return the unsigned 32-bit integer from @var{bv} at " + "@var{index} using the native endianness.") +#define FUNC_NAME s_scm_bytevector_u32_native_ref +{ +#if SIZEOF_VOID_P > 4 + INTEGER_NATIVE_REF (32, unsigned); +#else + LARGE_INTEGER_NATIVE_REF (32, unsigned); +#endif +} +#undef FUNC_NAME + +SCM_DEFINE (scm_bytevector_s32_native_ref, "bytevector-s32-native-ref", + 2, 0, 0, + (SCM bv, SCM index), + "Return the unsigned 32-bit integer from @var{bv} at " + "@var{index} using the native endianness.") +#define FUNC_NAME s_scm_bytevector_s32_native_ref +{ +#if SIZEOF_VOID_P > 4 + INTEGER_NATIVE_REF (32, signed); +#else + LARGE_INTEGER_NATIVE_REF (32, signed); +#endif +} +#undef FUNC_NAME + +SCM_DEFINE (scm_bytevector_u32_set_x, "bytevector-u32-set!", + 4, 0, 0, + (SCM bv, SCM index, SCM value, SCM endianness), + "Store @var{value} in @var{bv} at @var{index} according to " + "@var{endianness}.") +#define FUNC_NAME s_scm_bytevector_u32_set_x +{ +#if SIZEOF_VOID_P > 4 + INTEGER_SET (32, unsigned); +#else + LARGE_INTEGER_SET (32, unsigned); +#endif +} +#undef FUNC_NAME + +SCM_DEFINE (scm_bytevector_s32_set_x, "bytevector-s32-set!", + 4, 0, 0, + (SCM bv, SCM index, SCM value, SCM endianness), + "Store @var{value} in @var{bv} at @var{index} according to " + "@var{endianness}.") +#define FUNC_NAME s_scm_bytevector_s32_set_x +{ +#if SIZEOF_VOID_P > 4 + INTEGER_SET (32, signed); +#else + LARGE_INTEGER_SET (32, signed); +#endif +} +#undef FUNC_NAME + +SCM_DEFINE (scm_bytevector_u32_native_set_x, "bytevector-u32-native-set!", + 3, 0, 0, + (SCM bv, SCM index, SCM value), + "Store the unsigned integer @var{value} at index @var{index} " + "of @var{bv} using the native endianness.") +#define FUNC_NAME s_scm_bytevector_u32_native_set_x +{ +#if SIZEOF_VOID_P > 4 + INTEGER_NATIVE_SET (32, unsigned); +#else + LARGE_INTEGER_NATIVE_SET (32, unsigned); +#endif +} +#undef FUNC_NAME + +SCM_DEFINE (scm_bytevector_s32_native_set_x, "bytevector-s32-native-set!", + 3, 0, 0, + (SCM bv, SCM index, SCM value), + "Store the signed integer @var{value} at index @var{index} " + "of @var{bv} using the native endianness.") +#define FUNC_NAME s_scm_bytevector_s32_native_set_x +{ +#if SIZEOF_VOID_P > 4 + INTEGER_NATIVE_SET (32, signed); +#else + LARGE_INTEGER_NATIVE_SET (32, signed); +#endif +} +#undef FUNC_NAME + + + +/* Operations on 64-bit integers. */ + +/* For 64-bit integers, we use only the `large_{ref,set}' variant. */ + +SCM_DEFINE (scm_bytevector_u64_ref, "bytevector-u64-ref", + 3, 0, 0, + (SCM bv, SCM index, SCM endianness), + "Return the unsigned 64-bit integer from @var{bv} at " + "@var{index}.") +#define FUNC_NAME s_scm_bytevector_u64_ref +{ + LARGE_INTEGER_REF (64, unsigned); +} +#undef FUNC_NAME + +SCM_DEFINE (scm_bytevector_s64_ref, "bytevector-s64-ref", + 3, 0, 0, + (SCM bv, SCM index, SCM endianness), + "Return the signed 64-bit integer from @var{bv} at " + "@var{index}.") +#define FUNC_NAME s_scm_bytevector_s64_ref +{ + LARGE_INTEGER_REF (64, signed); +} +#undef FUNC_NAME + +SCM_DEFINE (scm_bytevector_u64_native_ref, "bytevector-u64-native-ref", + 2, 0, 0, + (SCM bv, SCM index), + "Return the unsigned 64-bit integer from @var{bv} at " + "@var{index} using the native endianness.") +#define FUNC_NAME s_scm_bytevector_u64_native_ref +{ + LARGE_INTEGER_NATIVE_REF (64, unsigned); +} +#undef FUNC_NAME + +SCM_DEFINE (scm_bytevector_s64_native_ref, "bytevector-s64-native-ref", + 2, 0, 0, + (SCM bv, SCM index), + "Return the unsigned 64-bit integer from @var{bv} at " + "@var{index} using the native endianness.") +#define FUNC_NAME s_scm_bytevector_s64_native_ref +{ + LARGE_INTEGER_NATIVE_REF (64, signed); +} +#undef FUNC_NAME + +SCM_DEFINE (scm_bytevector_u64_set_x, "bytevector-u64-set!", + 4, 0, 0, + (SCM bv, SCM index, SCM value, SCM endianness), + "Store @var{value} in @var{bv} at @var{index} according to " + "@var{endianness}.") +#define FUNC_NAME s_scm_bytevector_u64_set_x +{ + LARGE_INTEGER_SET (64, unsigned); +} +#undef FUNC_NAME + +SCM_DEFINE (scm_bytevector_s64_set_x, "bytevector-s64-set!", + 4, 0, 0, + (SCM bv, SCM index, SCM value, SCM endianness), + "Store @var{value} in @var{bv} at @var{index} according to " + "@var{endianness}.") +#define FUNC_NAME s_scm_bytevector_s64_set_x +{ + LARGE_INTEGER_SET (64, signed); +} +#undef FUNC_NAME + +SCM_DEFINE (scm_bytevector_u64_native_set_x, "bytevector-u64-native-set!", + 3, 0, 0, + (SCM bv, SCM index, SCM value), + "Store the unsigned integer @var{value} at index @var{index} " + "of @var{bv} using the native endianness.") +#define FUNC_NAME s_scm_bytevector_u64_native_set_x +{ + LARGE_INTEGER_NATIVE_SET (64, unsigned); +} +#undef FUNC_NAME + +SCM_DEFINE (scm_bytevector_s64_native_set_x, "bytevector-s64-native-set!", + 3, 0, 0, + (SCM bv, SCM index, SCM value), + "Store the signed integer @var{value} at index @var{index} " + "of @var{bv} using the native endianness.") +#define FUNC_NAME s_scm_bytevector_s64_native_set_x +{ + LARGE_INTEGER_NATIVE_SET (64, signed); +} +#undef FUNC_NAME + + + +/* Operations on IEEE-754 numbers. */ + +/* There are two possible word endians, visible in glibc's . + However, in R6RS, when the endianness is `little', little endian is + assumed for both the byte order and the word order. This is clear from + Section 2.1 of R6RS-lib (in response to + http://www.r6rs.org/formal-comments/comment-187.txt). */ + + +/* Convert to/from a floating-point number with different endianness. This + method is probably not the most efficient but it should be portable. */ + +static inline void +float_to_foreign_endianness (union scm_ieee754_float *target, + float source) +{ + union scm_ieee754_float src; + + src.f = source; + +#ifdef WORDS_BIGENDIAN + /* Assuming little endian for both byte and word order. */ + target->little_endian.negative = src.big_endian.negative; + target->little_endian.exponent = src.big_endian.exponent; + target->little_endian.mantissa = src.big_endian.mantissa; +#else + target->big_endian.negative = src.little_endian.negative; + target->big_endian.exponent = src.little_endian.exponent; + target->big_endian.mantissa = src.little_endian.mantissa; +#endif +} + +static inline float +float_from_foreign_endianness (const union scm_ieee754_float *source) +{ + union scm_ieee754_float result; + +#ifdef WORDS_BIGENDIAN + /* Assuming little endian for both byte and word order. */ + result.big_endian.negative = source->little_endian.negative; + result.big_endian.exponent = source->little_endian.exponent; + result.big_endian.mantissa = source->little_endian.mantissa; +#else + result.little_endian.negative = source->big_endian.negative; + result.little_endian.exponent = source->big_endian.exponent; + result.little_endian.mantissa = source->big_endian.mantissa; +#endif + + return (result.f); +} + +static inline void +double_to_foreign_endianness (union scm_ieee754_double *target, + double source) +{ + union scm_ieee754_double src; + + src.d = source; + +#ifdef WORDS_BIGENDIAN + /* Assuming little endian for both byte and word order. */ + target->little_little_endian.negative = src.big_endian.negative; + target->little_little_endian.exponent = src.big_endian.exponent; + target->little_little_endian.mantissa0 = src.big_endian.mantissa0; + target->little_little_endian.mantissa1 = src.big_endian.mantissa1; +#else + target->big_endian.negative = src.little_little_endian.negative; + target->big_endian.exponent = src.little_little_endian.exponent; + target->big_endian.mantissa0 = src.little_little_endian.mantissa0; + target->big_endian.mantissa1 = src.little_little_endian.mantissa1; +#endif +} + +static inline double +double_from_foreign_endianness (const union scm_ieee754_double *source) +{ + union scm_ieee754_double result; + +#ifdef WORDS_BIGENDIAN + /* Assuming little endian for both byte and word order. */ + result.big_endian.negative = source->little_little_endian.negative; + result.big_endian.exponent = source->little_little_endian.exponent; + result.big_endian.mantissa0 = source->little_little_endian.mantissa0; + result.big_endian.mantissa1 = source->little_little_endian.mantissa1; +#else + result.little_little_endian.negative = source->big_endian.negative; + result.little_little_endian.exponent = source->big_endian.exponent; + result.little_little_endian.mantissa0 = source->big_endian.mantissa0; + result.little_little_endian.mantissa1 = source->big_endian.mantissa1; +#endif + + return (result.d); +} + +/* Template macros to abstract over doubles and floats. + XXX: Guile can only convert to/from doubles. */ +#define IEEE754_UNION(_c_type) union scm_ieee754_ ## _c_type +#define IEEE754_TO_SCM(_c_type) scm_from_double +#define IEEE754_FROM_SCM(_c_type) scm_to_double +#define IEEE754_FROM_FOREIGN_ENDIANNESS(_c_type) \ + _c_type ## _from_foreign_endianness +#define IEEE754_TO_FOREIGN_ENDIANNESS(_c_type) \ + _c_type ## _to_foreign_endianness + + +/* Templace getters and setters. */ + +#define IEEE754_ACCESSOR_PROLOGUE(_type) \ + INTEGER_ACCESSOR_PROLOGUE (sizeof (_type) << 3UL, signed); + +#define IEEE754_REF(_type) \ + _type c_result; \ + \ + IEEE754_ACCESSOR_PROLOGUE (_type); \ + SCM_VALIDATE_SYMBOL (3, endianness); \ + \ + if (scm_is_eq (endianness, scm_i_native_endianness)) \ + memcpy (&c_result, &c_bv[c_index], sizeof (c_result)); \ + else \ + { \ + IEEE754_UNION (_type) c_raw; \ + \ + memcpy (&c_raw, &c_bv[c_index], sizeof (c_raw)); \ + c_result = \ + IEEE754_FROM_FOREIGN_ENDIANNESS (_type) (&c_raw); \ + } \ + \ + return (IEEE754_TO_SCM (_type) (c_result)); + +#define IEEE754_NATIVE_REF(_type) \ + _type c_result; \ + \ + IEEE754_ACCESSOR_PROLOGUE (_type); \ + \ + memcpy (&c_result, &c_bv[c_index], sizeof (c_result)); \ + return (IEEE754_TO_SCM (_type) (c_result)); + +#define IEEE754_SET(_type) \ + _type c_value; \ + \ + IEEE754_ACCESSOR_PROLOGUE (_type); \ + SCM_VALIDATE_REAL (3, value); \ + SCM_VALIDATE_SYMBOL (4, endianness); \ + c_value = IEEE754_FROM_SCM (_type) (value); \ + \ + if (scm_is_eq (endianness, scm_i_native_endianness)) \ + memcpy (&c_bv[c_index], &c_value, sizeof (c_value)); \ + else \ + { \ + IEEE754_UNION (_type) c_raw; \ + \ + IEEE754_TO_FOREIGN_ENDIANNESS (_type) (&c_raw, c_value); \ + memcpy (&c_bv[c_index], &c_raw, sizeof (c_raw)); \ + } \ + \ + return SCM_UNSPECIFIED; + +#define IEEE754_NATIVE_SET(_type) \ + _type c_value; \ + \ + IEEE754_ACCESSOR_PROLOGUE (_type); \ + SCM_VALIDATE_REAL (3, value); \ + c_value = IEEE754_FROM_SCM (_type) (value); \ + \ + memcpy (&c_bv[c_index], &c_value, sizeof (c_value)); \ + return SCM_UNSPECIFIED; + + +/* Single precision. */ + +SCM_DEFINE (scm_bytevector_ieee_single_ref, + "bytevector-ieee-single-ref", + 3, 0, 0, + (SCM bv, SCM index, SCM endianness), + "Return the IEEE-754 single from @var{bv} at " + "@var{index}.") +#define FUNC_NAME s_scm_bytevector_ieee_single_ref +{ + IEEE754_REF (float); +} +#undef FUNC_NAME + +SCM_DEFINE (scm_bytevector_ieee_single_native_ref, + "bytevector-ieee-single-native-ref", + 2, 0, 0, + (SCM bv, SCM index), + "Return the IEEE-754 single from @var{bv} at " + "@var{index} using the native endianness.") +#define FUNC_NAME s_scm_bytevector_ieee_single_native_ref +{ + IEEE754_NATIVE_REF (float); +} +#undef FUNC_NAME + +SCM_DEFINE (scm_bytevector_ieee_single_set_x, + "bytevector-ieee-single-set!", + 4, 0, 0, + (SCM bv, SCM index, SCM value, SCM endianness), + "Store real @var{value} in @var{bv} at @var{index} according to " + "@var{endianness}.") +#define FUNC_NAME s_scm_bytevector_ieee_single_set_x +{ + IEEE754_SET (float); +} +#undef FUNC_NAME + +SCM_DEFINE (scm_bytevector_ieee_single_native_set_x, + "bytevector-ieee-single-native-set!", + 3, 0, 0, + (SCM bv, SCM index, SCM value), + "Store the real @var{value} at index @var{index} " + "of @var{bv} using the native endianness.") +#define FUNC_NAME s_scm_bytevector_ieee_single_native_set_x +{ + IEEE754_NATIVE_SET (float); +} +#undef FUNC_NAME + + +/* Double precision. */ + +SCM_DEFINE (scm_bytevector_ieee_double_ref, + "bytevector-ieee-double-ref", + 3, 0, 0, + (SCM bv, SCM index, SCM endianness), + "Return the IEEE-754 double from @var{bv} at " + "@var{index}.") +#define FUNC_NAME s_scm_bytevector_ieee_double_ref +{ + IEEE754_REF (double); +} +#undef FUNC_NAME + +SCM_DEFINE (scm_bytevector_ieee_double_native_ref, + "bytevector-ieee-double-native-ref", + 2, 0, 0, + (SCM bv, SCM index), + "Return the IEEE-754 double from @var{bv} at " + "@var{index} using the native endianness.") +#define FUNC_NAME s_scm_bytevector_ieee_double_native_ref +{ + IEEE754_NATIVE_REF (double); +} +#undef FUNC_NAME + +SCM_DEFINE (scm_bytevector_ieee_double_set_x, + "bytevector-ieee-double-set!", + 4, 0, 0, + (SCM bv, SCM index, SCM value, SCM endianness), + "Store real @var{value} in @var{bv} at @var{index} according to " + "@var{endianness}.") +#define FUNC_NAME s_scm_bytevector_ieee_double_set_x +{ + IEEE754_SET (double); +} +#undef FUNC_NAME + +SCM_DEFINE (scm_bytevector_ieee_double_native_set_x, + "bytevector-ieee-double-native-set!", + 3, 0, 0, + (SCM bv, SCM index, SCM value), + "Store the real @var{value} at index @var{index} " + "of @var{bv} using the native endianness.") +#define FUNC_NAME s_scm_bytevector_ieee_double_native_set_x +{ + IEEE754_NATIVE_SET (double); +} +#undef FUNC_NAME + + +#undef IEEE754_UNION +#undef IEEE754_TO_SCM +#undef IEEE754_FROM_SCM +#undef IEEE754_FROM_FOREIGN_ENDIANNESS +#undef IEEE754_TO_FOREIGN_ENDIANNESS +#undef IEEE754_REF +#undef IEEE754_NATIVE_REF +#undef IEEE754_SET +#undef IEEE754_NATIVE_SET + + +/* Operations on strings. */ + + +/* Produce a function that returns the length of a UTF-encoded string. */ +#define UTF_STRLEN_FUNCTION(_utf_width) \ +static inline size_t \ +utf ## _utf_width ## _strlen (const uint ## _utf_width ## _t *str) \ +{ \ + size_t len = 0; \ + const uint ## _utf_width ## _t *ptr; \ + for (ptr = str; \ + *ptr != 0; \ + ptr++) \ + { \ + len++; \ + } \ + \ + return (len * ((_utf_width) / 8)); \ +} + +UTF_STRLEN_FUNCTION (8) + + +/* Return the length (in bytes) of STR, a UTF-(UTF_WIDTH) encoded string. */ +#define UTF_STRLEN(_utf_width, _str) \ + utf ## _utf_width ## _strlen (_str) + +/* Return the "portable" name of the UTF encoding of size UTF_WIDTH and + ENDIANNESS (Gnulib's `iconv_open' module guarantees the portability of the + encoding name). */ +static inline void +utf_encoding_name (char *name, size_t utf_width, SCM endianness) +{ + strcpy (name, "UTF-"); + strcat (name, ((utf_width == 8) + ? "8" + : ((utf_width == 16) + ? "16" + : ((utf_width == 32) + ? "32" + : "??")))); + strcat (name, + ((scm_is_eq (endianness, scm_sym_big)) + ? "BE" + : ((scm_is_eq (endianness, scm_sym_little)) + ? "LE" + : "unknown"))); +} + +/* Maximum length of a UTF encoding name. */ +#define MAX_UTF_ENCODING_NAME_LEN 16 + +/* Produce the body of a `string->utf' function. */ +#define STRING_TO_UTF(_utf_width) \ + SCM utf; \ + int err; \ + char *c_str; \ + char c_utf_name[MAX_UTF_ENCODING_NAME_LEN]; \ + char *c_utf = NULL, *c_locale; \ + size_t c_strlen, c_raw_strlen, c_utf_len = 0; \ + \ + SCM_VALIDATE_STRING (1, str); \ + if (endianness == SCM_UNDEFINED) \ + endianness = scm_sym_big; \ + else \ + SCM_VALIDATE_SYMBOL (2, endianness); \ + \ + c_strlen = scm_c_string_length (str); \ + c_raw_strlen = c_strlen * ((_utf_width) / 8); \ + do \ + { \ + c_str = (char *) alloca (c_raw_strlen + 1); \ + c_raw_strlen = scm_to_locale_stringbuf (str, c_str, c_strlen); \ + } \ + while (c_raw_strlen > c_strlen); \ + c_str[c_raw_strlen] = '\0'; \ + \ + utf_encoding_name (c_utf_name, (_utf_width), endianness); \ + \ + c_locale = (char *) alloca (strlen (locale_charset ()) + 1); \ + strcpy (c_locale, locale_charset ()); \ + \ + err = mem_iconveh (c_str, c_raw_strlen, \ + c_locale, c_utf_name, \ + iconveh_question_mark, NULL, \ + &c_utf, &c_utf_len); \ + if (SCM_UNLIKELY (err)) \ + scm_syserror_msg (FUNC_NAME, "failed to convert string: ~A", \ + scm_list_1 (str), err); \ + else \ + /* C_UTF is null-terminated. */ \ + utf = scm_c_take_bytevector ((signed char *) c_utf, \ + c_utf_len); \ + \ + return (utf); + + + +SCM_DEFINE (scm_string_to_utf8, "string->utf8", + 1, 0, 0, + (SCM str), + "Return a newly allocated bytevector that contains the UTF-8 " + "encoding of @var{str}.") +#define FUNC_NAME s_scm_string_to_utf8 +{ + SCM utf; + char *c_str; + uint8_t *c_utf; + size_t c_strlen, c_raw_strlen; + + SCM_VALIDATE_STRING (1, str); + + c_strlen = scm_c_string_length (str); + c_raw_strlen = c_strlen; + do + { + c_str = (char *) alloca (c_raw_strlen + 1); + c_raw_strlen = scm_to_locale_stringbuf (str, c_str, c_strlen); + } + while (c_raw_strlen > c_strlen); + c_str[c_raw_strlen] = '\0'; + + c_utf = u8_strconv_from_locale (c_str); + if (SCM_UNLIKELY (c_utf == NULL)) + scm_syserror (FUNC_NAME); + else + /* C_UTF is null-terminated. */ + utf = scm_c_take_bytevector ((signed char *) c_utf, + UTF_STRLEN (8, c_utf)); + + return (utf); +} +#undef FUNC_NAME + +SCM_DEFINE (scm_string_to_utf16, "string->utf16", + 1, 1, 0, + (SCM str, SCM endianness), + "Return a newly allocated bytevector that contains the UTF-16 " + "encoding of @var{str}.") +#define FUNC_NAME s_scm_string_to_utf16 +{ + STRING_TO_UTF (16); +} +#undef FUNC_NAME + +SCM_DEFINE (scm_string_to_utf32, "string->utf32", + 1, 1, 0, + (SCM str, SCM endianness), + "Return a newly allocated bytevector that contains the UTF-32 " + "encoding of @var{str}.") +#define FUNC_NAME s_scm_string_to_utf32 +{ + STRING_TO_UTF (32); +} +#undef FUNC_NAME + + +/* Produce the body of a function that converts a UTF-encoded bytevector to a + string. */ +#define UTF_TO_STRING(_utf_width) \ + SCM str = SCM_BOOL_F; \ + int err; \ + char *c_str = NULL, *c_locale; \ + char c_utf_name[MAX_UTF_ENCODING_NAME_LEN]; \ + const char *c_utf; \ + size_t c_strlen = 0, c_utf_len; \ + \ + SCM_VALIDATE_BYTEVECTOR (1, utf); \ + if (endianness == SCM_UNDEFINED) \ + endianness = scm_sym_big; \ + else \ + SCM_VALIDATE_SYMBOL (2, endianness); \ + \ + c_utf_len = SCM_BYTEVECTOR_LENGTH (utf); \ + c_utf = (char *) SCM_BYTEVECTOR_CONTENTS (utf); \ + utf_encoding_name (c_utf_name, (_utf_width), endianness); \ + \ + c_locale = (char *) alloca (strlen (locale_charset ()) + 1); \ + strcpy (c_locale, locale_charset ()); \ + \ + err = mem_iconveh (c_utf, c_utf_len, \ + c_utf_name, c_locale, \ + iconveh_question_mark, NULL, \ + &c_str, &c_strlen); \ + if (SCM_UNLIKELY (err)) \ + scm_syserror_msg (FUNC_NAME, "failed to convert to string: ~A", \ + scm_list_1 (utf), err); \ + else \ + /* C_STR is null-terminated. */ \ + str = scm_take_locale_stringn (c_str, c_strlen); \ + \ + return (str); + + +SCM_DEFINE (scm_utf8_to_string, "utf8->string", + 1, 0, 0, + (SCM utf), + "Return a newly allocate string that contains from the UTF-8-" + "encoded contents of bytevector @var{utf}.") +#define FUNC_NAME s_scm_utf8_to_string +{ + SCM str; + int err; + char *c_str = NULL, *c_locale; + const char *c_utf; + size_t c_utf_len, c_strlen = 0; + + SCM_VALIDATE_BYTEVECTOR (1, utf); + + c_utf_len = SCM_BYTEVECTOR_LENGTH (utf); + + c_locale = (char *) alloca (strlen (locale_charset ()) + 1); + strcpy (c_locale, locale_charset ()); + + c_utf = (char *) SCM_BYTEVECTOR_CONTENTS (utf); + err = mem_iconveh (c_utf, c_utf_len, + "UTF-8", c_locale, + iconveh_question_mark, NULL, + &c_str, &c_strlen); + if (SCM_UNLIKELY (err)) + scm_syserror_msg (FUNC_NAME, "failed to convert to string: ~A", + scm_list_1 (utf), err); + else + /* C_STR is null-terminated. */ + str = scm_take_locale_stringn (c_str, c_strlen); + + return (str); +} +#undef FUNC_NAME + +SCM_DEFINE (scm_utf16_to_string, "utf16->string", + 1, 1, 0, + (SCM utf, SCM endianness), + "Return a newly allocate string that contains from the UTF-16-" + "encoded contents of bytevector @var{utf}.") +#define FUNC_NAME s_scm_utf16_to_string +{ + UTF_TO_STRING (16); +} +#undef FUNC_NAME + +SCM_DEFINE (scm_utf32_to_string, "utf32->string", + 1, 1, 0, + (SCM utf, SCM endianness), + "Return a newly allocate string that contains from the UTF-32-" + "encoded contents of bytevector @var{utf}.") +#define FUNC_NAME s_scm_utf32_to_string +{ + UTF_TO_STRING (32); +} +#undef FUNC_NAME + + + +/* Initialization. */ + +void +scm_bootstrap_bytevectors (void) +{ + /* The SMOB type must be instantiated here because the + generalized-vector API may want to access bytevectors even though + `(rnrs bytevector)' hasn't been loaded. */ + scm_tc16_bytevector = scm_make_smob_type ("bytevector", 0); + scm_set_smob_free (scm_tc16_bytevector, free_bytevector); + scm_set_smob_print (scm_tc16_bytevector, print_bytevector); + scm_set_smob_equalp (scm_tc16_bytevector, bytevector_equal_p); + + scm_null_bytevector = + scm_gc_protect_object (make_bytevector_from_buffer (0, NULL)); + +#ifdef WORDS_BIGENDIAN + scm_i_native_endianness = scm_permanent_object (scm_from_locale_symbol ("big")); +#else + scm_i_native_endianness = scm_permanent_object (scm_from_locale_symbol ("little")); +#endif + + scm_c_register_extension ("libguile", "scm_init_bytevectors", + (scm_t_extension_init_func) scm_init_bytevectors, + NULL); +} + +void +scm_init_bytevectors (void) +{ +#include "libguile/bytevectors.x" + + scm_endianness_big = scm_sym_big; + scm_endianness_little = scm_sym_little; +} diff --git a/libguile/bytevectors.h b/libguile/bytevectors.h new file mode 100644 index 000000000..cb2726251 --- /dev/null +++ b/libguile/bytevectors.h @@ -0,0 +1,146 @@ +#ifndef SCM_BYTEVECTORS_H +#define SCM_BYTEVECTORS_H + +/* Copyright (C) 2009 Free Software Foundation, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + + + +#include "libguile/__scm.h" + + +/* R6RS bytevectors. */ + +#define SCM_BYTEVECTOR_LENGTH(_bv) \ + ((size_t) SCM_SMOB_DATA (_bv)) +#define SCM_BYTEVECTOR_CONTENTS(_bv) \ + (SCM_BYTEVECTOR_INLINE_P (_bv) \ + ? (signed char *) SCM_SMOB_OBJECT_2_LOC (_bv) \ + : (signed char *) SCM_SMOB_DATA_2 (_bv)) + + +SCM_API SCM scm_endianness_big; +SCM_API SCM scm_endianness_little; + +SCM_API SCM scm_c_make_bytevector (size_t); +SCM_API int scm_is_bytevector (SCM); +SCM_API size_t scm_c_bytevector_length (SCM); +SCM_API scm_t_uint8 scm_c_bytevector_ref (SCM, size_t); +SCM_API void scm_c_bytevector_set_x (SCM, size_t, scm_t_uint8); + +SCM_API SCM scm_make_bytevector (SCM, SCM); +SCM_API SCM scm_native_endianness (void); +SCM_API SCM scm_bytevector_p (SCM); +SCM_API SCM scm_bytevector_length (SCM); +SCM_API SCM scm_bytevector_eq_p (SCM, SCM); +SCM_API SCM scm_bytevector_fill_x (SCM, SCM); +SCM_API SCM scm_bytevector_copy_x (SCM, SCM, SCM, SCM, SCM); +SCM_API SCM scm_bytevector_copy (SCM); + +SCM_API SCM scm_uniform_array_to_bytevector (SCM); + +SCM_API SCM scm_bytevector_to_u8_list (SCM); +SCM_API SCM scm_u8_list_to_bytevector (SCM); +SCM_API SCM scm_uint_list_to_bytevector (SCM, SCM, SCM); +SCM_API SCM scm_bytevector_to_uint_list (SCM, SCM, SCM); +SCM_API SCM scm_sint_list_to_bytevector (SCM, SCM, SCM); +SCM_API SCM scm_bytevector_to_sint_list (SCM, SCM, SCM); + +SCM_API SCM scm_bytevector_u16_native_ref (SCM, SCM); +SCM_API SCM scm_bytevector_s16_native_ref (SCM, SCM); +SCM_API SCM scm_bytevector_u32_native_ref (SCM, SCM); +SCM_API SCM scm_bytevector_s32_native_ref (SCM, SCM); +SCM_API SCM scm_bytevector_u64_native_ref (SCM, SCM); +SCM_API SCM scm_bytevector_s64_native_ref (SCM, SCM); +SCM_API SCM scm_bytevector_u8_ref (SCM, SCM); +SCM_API SCM scm_bytevector_s8_ref (SCM, SCM); +SCM_API SCM scm_bytevector_uint_ref (SCM, SCM, SCM, SCM); +SCM_API SCM scm_bytevector_sint_ref (SCM, SCM, SCM, SCM); +SCM_API SCM scm_bytevector_u16_ref (SCM, SCM, SCM); +SCM_API SCM scm_bytevector_s16_ref (SCM, SCM, SCM); +SCM_API SCM scm_bytevector_u32_ref (SCM, SCM, SCM); +SCM_API SCM scm_bytevector_s32_ref (SCM, SCM, SCM); +SCM_API SCM scm_bytevector_u64_ref (SCM, SCM, SCM); +SCM_API SCM scm_bytevector_s64_ref (SCM, SCM, SCM); +SCM_API SCM scm_bytevector_u16_native_set_x (SCM, SCM, SCM); +SCM_API SCM scm_bytevector_s16_native_set_x (SCM, SCM, SCM); +SCM_API SCM scm_bytevector_u32_native_set_x (SCM, SCM, SCM); +SCM_API SCM scm_bytevector_s32_native_set_x (SCM, SCM, SCM); +SCM_API SCM scm_bytevector_u64_native_set_x (SCM, SCM, SCM); +SCM_API SCM scm_bytevector_s64_native_set_x (SCM, SCM, SCM); +SCM_API SCM scm_bytevector_u8_set_x (SCM, SCM, SCM); +SCM_API SCM scm_bytevector_s8_set_x (SCM, SCM, SCM); +SCM_API SCM scm_bytevector_uint_set_x (SCM, SCM, SCM, SCM, SCM); +SCM_API SCM scm_bytevector_sint_set_x (SCM, SCM, SCM, SCM, SCM); +SCM_API SCM scm_bytevector_u16_set_x (SCM, SCM, SCM, SCM); +SCM_API SCM scm_bytevector_s16_set_x (SCM, SCM, SCM, SCM); +SCM_API SCM scm_bytevector_u32_set_x (SCM, SCM, SCM, SCM); +SCM_API SCM scm_bytevector_s32_set_x (SCM, SCM, SCM, SCM); +SCM_API SCM scm_bytevector_u64_set_x (SCM, SCM, SCM, SCM); +SCM_API SCM scm_bytevector_s64_set_x (SCM, SCM, SCM, SCM); +SCM_API SCM scm_bytevector_ieee_single_ref (SCM, SCM, SCM); +SCM_API SCM scm_bytevector_ieee_single_native_ref (SCM, SCM); +SCM_API SCM scm_bytevector_ieee_single_set_x (SCM, SCM, SCM, SCM); +SCM_API SCM scm_bytevector_ieee_single_native_set_x (SCM, SCM, SCM); +SCM_API SCM scm_bytevector_ieee_double_ref (SCM, SCM, SCM); +SCM_API SCM scm_bytevector_ieee_double_native_ref (SCM, SCM); +SCM_API SCM scm_bytevector_ieee_double_set_x (SCM, SCM, SCM, SCM); +SCM_API SCM scm_bytevector_ieee_double_native_set_x (SCM, SCM, SCM); +SCM_API SCM scm_string_to_utf8 (SCM); +SCM_API SCM scm_string_to_utf16 (SCM, SCM); +SCM_API SCM scm_string_to_utf32 (SCM, SCM); +SCM_API SCM scm_utf8_to_string (SCM); +SCM_API SCM scm_utf16_to_string (SCM, SCM); +SCM_API SCM scm_utf32_to_string (SCM, SCM); + + + +/* Internal API. */ + +/* The threshold (in octets) under which bytevectors are stored "in-line", + i.e., without allocating memory beside the SMOB itself (a double cell). + This optimization is necessary since small bytevectors are expected to be + common. */ +#define SCM_BYTEVECTOR_P(_bv) \ + SCM_SMOB_PREDICATE (scm_tc16_bytevector, _bv) +#define SCM_BYTEVECTOR_INLINE_THRESHOLD (2 * sizeof (SCM)) +#define SCM_BYTEVECTOR_INLINEABLE_SIZE_P(_size) \ + ((_size) <= SCM_BYTEVECTOR_INLINE_THRESHOLD) +#define SCM_BYTEVECTOR_INLINE_P(_bv) \ + (SCM_BYTEVECTOR_INLINEABLE_SIZE_P (SCM_BYTEVECTOR_LENGTH (_bv))) + +/* Hint that is passed to `scm_gc_malloc ()' and friends. */ +#define SCM_GC_BYTEVECTOR "bytevector" + +SCM_INTERNAL void scm_bootstrap_bytevectors (void); +SCM_INTERNAL void scm_init_bytevectors (void); + +SCM_INTERNAL scm_t_bits scm_tc16_bytevector; +SCM_INTERNAL SCM scm_i_native_endianness; +SCM_INTERNAL SCM scm_c_take_bytevector (signed char *, size_t); + +#define scm_c_shrink_bytevector(_bv, _len) \ + (SCM_BYTEVECTOR_INLINE_P (_bv) \ + ? (_bv) \ + : scm_i_shrink_bytevector ((_bv), (_len))) + +SCM_INTERNAL SCM scm_i_shrink_bytevector (SCM, size_t); +SCM_INTERNAL void scm_i_bytevector_generalized_set_x (SCM, size_t, SCM); +SCM_INTERNAL SCM scm_null_bytevector; + +#endif /* SCM_BYTEVECTORS_H */ diff --git a/libguile/chars.c b/libguile/chars.c index 909e11d57..552a2d9c1 100644 --- a/libguile/chars.c +++ b/libguile/chars.c @@ -1,18 +1,19 @@ -/* Copyright (C) 1995,1996,1998, 2000, 2001, 2004, 2006, 2008 Free Software Foundation, Inc. +/* Copyright (C) 1995,1996,1998, 2000, 2001, 2004, 2006, 2008, 2009 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ @@ -23,6 +24,8 @@ #include #include +#include + #include "libguile/_scm.h" #include "libguile/validate.h" @@ -54,7 +57,7 @@ SCM_DEFINE1 (scm_char_eq_p, "char=?", scm_tc7_rpsubr, SCM_DEFINE1 (scm_char_less_p, "char?", scm_tc7_rpsubr, (SCM x, SCM y), - "Return @code{#t} iff @var{x} is greater than @var{y} in the ASCII\n" + "Return @code{#t} iff @var{x} is greater than @var{y} in the Unicode\n" "sequence, else @code{#f}.") #define FUNC_NAME s_scm_char_gr_p { @@ -91,7 +94,7 @@ SCM_DEFINE1 (scm_char_gr_p, "char>?", scm_tc7_rpsubr, SCM_DEFINE1 (scm_char_geq_p, "char>=?", scm_tc7_rpsubr, (SCM x, SCM y), "Return @code{#t} iff @var{x} is greater than or equal to @var{y} in the\n" - "ASCII sequence, else @code{#f}.") + "Unicode sequence, else @code{#f}.") #define FUNC_NAME s_scm_char_geq_p { SCM_VALIDATE_CHAR (1, x); @@ -103,7 +106,7 @@ SCM_DEFINE1 (scm_char_geq_p, "char>=?", scm_tc7_rpsubr, SCM_DEFINE1 (scm_char_ci_eq_p, "char-ci=?", scm_tc7_rpsubr, (SCM x, SCM y), "Return @code{#t} iff @var{x} is the same character as @var{y} ignoring\n" - "case, else @code{#f}.") + "case, else @code{#f}. Case is locale free and not context sensitive.") #define FUNC_NAME s_scm_char_ci_eq_p { SCM_VALIDATE_CHAR (1, x); @@ -114,8 +117,9 @@ SCM_DEFINE1 (scm_char_ci_eq_p, "char-ci=?", scm_tc7_rpsubr, SCM_DEFINE1 (scm_char_ci_less_p, "char-ci?", scm_tc7_rpsubr, (SCM x, SCM y), - "Return @code{#t} iff @var{x} is greater than @var{y} in the ASCII\n" - "sequence ignoring case, else @code{#f}.") + "Return @code{#t} iff the Unicode uppercase form of @var{x} is greater\n" + "than the Unicode uppercase form of @var{y} in the Unicode\n" + "sequence, else @code{#f}.") #define FUNC_NAME s_scm_char_ci_gr_p { SCM_VALIDATE_CHAR (1, x); @@ -150,8 +156,9 @@ SCM_DEFINE1 (scm_char_ci_gr_p, "char-ci>?", scm_tc7_rpsubr, SCM_DEFINE1 (scm_char_ci_geq_p, "char-ci>=?", scm_tc7_rpsubr, (SCM x, SCM y), - "Return @code{#t} iff @var{x} is greater than or equal to @var{y} in the\n" - "ASCII sequence ignoring case, else @code{#f}.") + "Return @code{#t} iff the Unicode uppercase form of @var{x} is greater\n" + "than or equal to the Unicode uppercase form of @var{y} in the\n" + "Unicode sequence, else @code{#f}.") #define FUNC_NAME s_scm_char_ci_geq_p { SCM_VALIDATE_CHAR (1, x); @@ -232,7 +239,7 @@ SCM_DEFINE (scm_char_to_integer, "char->integer", 1, 0, 0, #define FUNC_NAME s_scm_char_to_integer { SCM_VALIDATE_CHAR (1, chr); - return scm_from_ulong (SCM_CHAR(chr)); + return scm_from_uint32 (SCM_CHAR(chr)); } #undef FUNC_NAME @@ -243,7 +250,15 @@ SCM_DEFINE (scm_integer_to_char, "integer->char", 1, 0, 0, "Return the character at position @var{n} in the ASCII sequence.") #define FUNC_NAME s_scm_integer_to_char { - return SCM_MAKE_CHAR (scm_to_uchar (n)); + scm_t_wchar cn; + + cn = scm_to_wchar (n); + + /* Avoid the surrogates. */ + if (!SCM_IS_UNICODE_CHAR (cn)) + scm_out_of_range (FUNC_NAME, n); + + return SCM_MAKE_CHAR (cn); } #undef FUNC_NAME @@ -254,7 +269,7 @@ SCM_DEFINE (scm_char_upcase, "char-upcase", 1, 0, 0, #define FUNC_NAME s_scm_char_upcase { SCM_VALIDATE_CHAR (1, chr); - return SCM_MAKE_CHAR (toupper (SCM_CHAR (chr))); + return SCM_MAKE_CHAR (scm_c_upcase (SCM_CHAR (chr))); } #undef FUNC_NAME @@ -265,7 +280,7 @@ SCM_DEFINE (scm_char_downcase, "char-downcase", 1, 0, 0, #define FUNC_NAME s_scm_char_downcase { SCM_VALIDATE_CHAR (1, chr); - return SCM_MAKE_CHAR (tolower (SCM_CHAR(chr))); + return SCM_MAKE_CHAR (scm_c_downcase (SCM_CHAR(chr))); } #undef FUNC_NAME @@ -278,80 +293,121 @@ TODO: change name to scm_i_.. ? --hwn */ -int -scm_c_upcase (unsigned int c) +scm_t_wchar +scm_c_upcase (scm_t_wchar c) { - if (c <= UCHAR_MAX) - return toupper (c); - else + if (c > 255) return c; + + return toupper ((int) c); } -int -scm_c_downcase (unsigned int c) +scm_t_wchar +scm_c_downcase (scm_t_wchar c) { - if (c <= UCHAR_MAX) - return tolower (c); - else + if (c > 255) return c; + + return tolower ((int) c); } + -#ifdef _DCC -# define ASCII -#else -# if (('\n'=='\025') && (' '=='\100') && ('a'=='\201') && ('A'=='\301')) -# define EBCDIC -# endif /* (('\n'=='\025') && (' '=='\100') && ('a'=='\201') && ('A'=='\301')) */ -# if (('\n'=='\012') && (' '=='\040') && ('a'=='\141') && ('A'=='\101')) -# define ASCII -# endif /* (('\n'=='\012') && (' '=='\040') && ('a'=='\141') && ('A'=='\101')) */ -#endif /* def _DCC */ +/* There are a few sets of character names: R5RS, Guile + extensions for control characters, and leftover Guile extensions. + They are listed in order of precedence. */ +static const char *const scm_r5rs_charnames[] = { + "space", "newline" +}; -#ifdef EBCDIC -char *const scm_charnames[] = +static const scm_t_uint32 const scm_r5rs_charnums[] = { + 0x20, 0x0A +}; + +#define SCM_N_R5RS_CHARNAMES (sizeof (scm_r5rs_charnames) / sizeof (char *)) + +/* The abbreviated names for control characters. */ +static const char *const scm_C0_control_charnames[] = { + /* C0 controls */ + "nul", "soh", "stx", "etx", "eot", "enq", "ack", "bel", + "bs", "ht", "lf", "vt", "ff", "cr", "so", "si", + "dle", "dc1", "dc2", "dc3", "dc4", "nak", "syn", "etb", + "can", "em", "sub", "esc", "fs", "gs", "rs", "us", + "sp", "del" +}; + +static const scm_t_uint32 const scm_C0_control_charnums[] = { + 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, 0x7f +}; + +#define SCM_N_C0_CONTROL_CHARNAMES (sizeof (scm_C0_control_charnames) / sizeof (char *)) + +static const char *const scm_alt_charnames[] = { + "null", "backspace", "tab", "nl", "newline", "np", "page", "return", +}; + +static const scm_t_uint32 const scm_alt_charnums[] = { + 0x00, 0x08, 0x09, 0x0a, 0x0a, 0x0c, 0x0c, 0x0d +}; + +#define SCM_N_ALT_CHARNAMES (sizeof (scm_alt_charnames) / sizeof (char *)) + +/* Returns the string charname for a character if it exists, or NULL + otherwise. */ +const char * +scm_i_charname (SCM chr) { - "nul", "soh", "stx", "etx", "pf", "ht", "lc", "del", - 0 , 0 , "smm", "vt", "ff", "cr", "so", "si", - "dle", "dc1", "dc2", "dc3", "res", "nl", "bs", "il", - "can", "em", "cc", 0 , "ifs", "igs", "irs", "ius", - "ds", "sos", "fs", 0 , "byp", "lf", "eob", "pre", - 0 , 0 , "sm", 0 , 0 , "enq", "ack", "bel", - 0 , 0 , "syn", 0 , "pn", "rs", "uc", "eot", - 0 , 0 , 0 , 0 , "dc4", "nak", 0 , "sub", - "space", scm_s_newline, "tab", "backspace", "return", "page", "null"}; + size_t c; + scm_t_uint32 i = SCM_CHAR (chr); -const char scm_charnums[] = -"\000\001\002\003\004\005\006\007\ -\010\011\012\013\014\015\016\017\ -\020\021\022\023\024\025\026\027\ -\030\031\032\033\034\035\036\037\ -\040\041\042\043\044\045\046\047\ -\050\051\052\053\054\055\056\057\ -\060\061\062\063\064\065\066\067\ -\070\071\072\073\074\075\076\077\ - \n\t\b\r\f\0"; -#endif /* def EBCDIC */ -#ifdef ASCII -char *const scm_charnames[] = + for (c = 0; c < SCM_N_R5RS_CHARNAMES; c++) + if (scm_r5rs_charnums[c] == i) + return scm_r5rs_charnames[c]; + + for (c = 0; c < SCM_N_C0_CONTROL_CHARNAMES; c++) + if (scm_C0_control_charnums[c] == i) + return scm_C0_control_charnames[c]; + + for (c = 0; c < SCM_N_ALT_CHARNAMES; c++) + if (scm_alt_charnums[c] == i) + return scm_alt_charnames[i]; + + return NULL; +} + +/* Return a character from a string charname. */ +SCM +scm_i_charname_to_char (const char *charname, size_t charname_len) { - "nul","soh","stx","etx","eot","enq","ack","bel", - "bs", "ht", "newline", "vt", "np", "cr", "so", "si", - "dle","dc1","dc2","dc3","dc4","nak","syn","etb", - "can", "em","sub","esc", "fs", "gs", "rs", "us", - "space", "sp", "nl", "tab", "backspace", "return", "page", "null", "del"}; -const char scm_charnums[] = -"\000\001\002\003\004\005\006\007\ -\010\011\012\013\014\015\016\017\ -\020\021\022\023\024\025\026\027\ -\030\031\032\033\034\035\036\037\ - \n\t\b\r\f\0\177"; -#endif /* def ASCII */ + size_t c; -int scm_n_charnames = sizeof (scm_charnames) / sizeof (char *); + /* The R5RS charnames. These are supposed to be case + insensitive. */ + for (c = 0; c < SCM_N_R5RS_CHARNAMES; c++) + if ((strlen (scm_r5rs_charnames[c]) == charname_len) + && (!strncasecmp (scm_r5rs_charnames[c], charname, charname_len))) + return SCM_MAKE_CHAR (scm_r5rs_charnums[c]); + /* Then come the controls. These are not case sensitive. */ + for (c = 0; c < SCM_N_C0_CONTROL_CHARNAMES; c++) + if ((strlen (scm_C0_control_charnames[c]) == charname_len) + && (!strncasecmp (scm_C0_control_charnames[c], charname, charname_len))) + return SCM_MAKE_CHAR (scm_C0_control_charnums[c]); + + /* Lastly are some old names carried over for compatibility. */ + for (c = 0; c < SCM_N_ALT_CHARNAMES; c++) + if ((strlen (scm_alt_charnames[c]) == charname_len) + && (!strncasecmp (scm_alt_charnames[c], charname, charname_len))) + return SCM_MAKE_CHAR (scm_alt_charnums[c]); + + return SCM_BOOL_F; +} diff --git a/libguile/chars.h b/libguile/chars.h index 97c611af4..51adc21e5 100644 --- a/libguile/chars.h +++ b/libguile/chars.h @@ -3,39 +3,44 @@ #ifndef SCM_CHARS_H #define SCM_CHARS_H -/* Copyright (C) 1995,1996,2000,2001,2004, 2006, 2008 Free Software Foundation, Inc. +/* Copyright (C) 1995,1996,2000,2001,2004, 2006, 2008, 2009 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ #include "libguile/__scm.h" +#include "libguile/numbers.h" /* Immediate Characters */ #define SCM_CHARP(x) (SCM_ITAG8(x) == scm_tc8_char) -#define SCM_CHAR(x) ((unsigned int)SCM_ITAG8_DATA(x)) -#define SCM_MAKE_CHAR(x) SCM_MAKE_ITAG8((scm_t_bits) (unsigned char) (x), scm_tc8_char) +#define SCM_CHAR(x) ((scm_t_wchar)SCM_ITAG8_DATA(x)) - +#define SCM_MAKE_CHAR(x) \ + ((scm_t_int32) (x) < 0 \ + ? SCM_MAKE_ITAG8 ((scm_t_bits) (unsigned char) (x), scm_tc8_char) \ + : SCM_MAKE_ITAG8 ((scm_t_bits) (x), scm_tc8_char)) -SCM_API char *const scm_charnames[]; -SCM_API int scm_n_charnames; -SCM_API const char scm_charnums[]; +#define SCM_CODEPOINT_MAX (0x10ffff) +#define SCM_IS_UNICODE_CHAR(c) \ + ((scm_t_wchar) (c) <= 0xd7ff \ + || ((scm_t_wchar) (c) >= 0xe000 && (scm_t_wchar) (c) <= SCM_CODEPOINT_MAX)) @@ -60,8 +65,11 @@ SCM_API SCM scm_char_to_integer (SCM chr); SCM_API SCM scm_integer_to_char (SCM n); SCM_API SCM scm_char_upcase (SCM chr); SCM_API SCM scm_char_downcase (SCM chr); -SCM_API int scm_c_upcase (unsigned int c); -SCM_API int scm_c_downcase (unsigned int c); +SCM_API scm_t_wchar scm_c_upcase (scm_t_wchar c); +SCM_API scm_t_wchar scm_c_downcase (scm_t_wchar c); +SCM_INTERNAL const char *scm_i_charname (SCM chr); +SCM_INTERNAL SCM scm_i_charname_to_char (const char *charname, + size_t charname_len); SCM_INTERNAL void scm_init_chars (void); #endif /* SCM_CHARS_H */ diff --git a/libguile/continuations.c b/libguile/continuations.c index 5c833e687..1957d754f 100644 --- a/libguile/continuations.c +++ b/libguile/continuations.c @@ -1,18 +1,19 @@ /* Copyright (C) 1995,1996,1998,2000,2001,2004, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ @@ -85,8 +86,6 @@ scm_make_continuation (int *first) continuation->root = thread->continuation_root; continuation->dframe = scm_i_last_debug_frame (); src = thread->continuation_base; - SCM_NEWSMOB (cont, scm_tc16_continuation, continuation); - #if ! SCM_STACK_GROWS_UP src -= stack_size; #endif @@ -94,6 +93,8 @@ scm_make_continuation (int *first) memcpy (continuation->stack, src, sizeof (SCM_STACKITEM) * stack_size); continuation->vm_conts = scm_vm_capture_continuations (); + SCM_NEWSMOB (cont, scm_tc16_continuation, continuation); + *first = !setjmp (continuation->jmpbuf); if (*first) { diff --git a/libguile/continuations.h b/libguile/continuations.h index e5fd91f2e..08eec8f54 100644 --- a/libguile/continuations.h +++ b/libguile/continuations.h @@ -6,18 +6,19 @@ /* Copyright (C) 1995,1996,2000,2001, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/convert.c b/libguile/convert.c index 700deaa87..d87d72464 100644 --- a/libguile/convert.c +++ b/libguile/convert.c @@ -1,18 +1,19 @@ /* Copyright (C) 2002, 2006 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/convert.h b/libguile/convert.h index f834a6b1d..6ce7c2274 100644 --- a/libguile/convert.h +++ b/libguile/convert.h @@ -6,18 +6,19 @@ /* Copyright (C) 2002, 2006 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/debug-malloc.c b/libguile/debug-malloc.c index 4d04df5db..fa3612de2 100644 --- a/libguile/debug-malloc.c +++ b/libguile/debug-malloc.c @@ -1,18 +1,19 @@ /* Copyright (C) 2000, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ #ifdef HAVE_CONFIG_H diff --git a/libguile/debug-malloc.h b/libguile/debug-malloc.h index 1aa5221c6..7830adbac 100644 --- a/libguile/debug-malloc.h +++ b/libguile/debug-malloc.h @@ -6,18 +6,19 @@ /* Copyright (C) 2000,2001, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/debug.c b/libguile/debug.c index 62378921b..a214332d8 100644 --- a/libguile/debug.c +++ b/libguile/debug.c @@ -2,18 +2,19 @@ * Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2002, 2003, 2006, 2008, 2009 Free Software Foundation * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ @@ -21,6 +22,11 @@ # include #endif +#ifdef HAVE_GETRLIMIT +#include +#include +#endif + #include "libguile/_scm.h" #include "libguile/async.h" #include "libguile/eval.h" @@ -303,7 +309,7 @@ SCM_DEFINE (scm_procedure_name, "procedure-name", 1, 0, 0, SCM_VALIDATE_PROC (1, proc); switch (SCM_TYP7 (proc)) { case scm_tcs_subrs: - return SCM_SNAME (proc); + return SCM_SUBR_NAME (proc); default: { SCM name = scm_procedure_property (proc, scm_sym_name); @@ -395,6 +401,21 @@ SCM_DEFINE (scm_procedure_environment, "procedure-environment", 1, 0, 0, } #undef FUNC_NAME +SCM_DEFINE (scm_procedure_module, "procedure-module", 1, 0, 0, + (SCM proc), + "Return the module that was current when @var{proc} was defined.") +#define FUNC_NAME s_scm_procedure_module +{ + SCM_VALIDATE_PROC (SCM_ARG1, proc); + + if (scm_is_true (scm_program_p (proc))) + return scm_program_module (proc); + else + return scm_env_module (scm_procedure_environment (proc)); +} +#undef FUNC_NAME + + /* Eval in a local environment. We would like to have the ability to @@ -513,11 +534,32 @@ SCM_DEFINE (scm_debug_hang, "debug-hang", 0, 1, 0, #undef FUNC_NAME #endif +static void +init_stack_limit (void) +{ +#ifdef HAVE_GETRLIMIT + struct rlimit lim; + if (getrlimit (RLIMIT_STACK, &lim) == 0) + { + rlim_t bytes = lim.rlim_cur; + + /* set our internal stack limit to 80% of the rlimit. */ + if (bytes == RLIM_INFINITY) + bytes = lim.rlim_max; + + if (bytes != RLIM_INFINITY) + SCM_STACK_LIMIT = bytes * 8 / 10 / sizeof (scm_t_bits); + } + errno = 0; +#endif +} + void scm_init_debug () { + init_stack_limit (); scm_init_opts (scm_debug_options, scm_debug_opts); scm_tc16_memoized = scm_make_smob_type ("memoized", 0); diff --git a/libguile/debug.h b/libguile/debug.h index 4e94b3c15..20febdb71 100644 --- a/libguile/debug.h +++ b/libguile/debug.h @@ -7,18 +7,19 @@ * Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ @@ -140,6 +141,7 @@ SCM_API SCM scm_local_eval (SCM exp, SCM env); SCM_API SCM scm_reverse_lookup (SCM env, SCM data); SCM_API SCM scm_sys_start_stack (SCM info_id, SCM thunk); SCM_API SCM scm_procedure_environment (SCM proc); +SCM_API SCM scm_procedure_module (SCM proc); SCM_API SCM scm_procedure_source (SCM proc); SCM_API SCM scm_procedure_name (SCM proc); SCM_API SCM scm_memoized_environment (SCM m); diff --git a/libguile/deprecated.c b/libguile/deprecated.c index 979de84e1..57a2f0657 100644 --- a/libguile/deprecated.c +++ b/libguile/deprecated.c @@ -5,18 +5,19 @@ /* Copyright (C) 2003, 2004, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ #ifdef HAVE_CONFIG_H diff --git a/libguile/deprecated.h b/libguile/deprecated.h index 9a0862c3e..5b443c761 100644 --- a/libguile/deprecated.h +++ b/libguile/deprecated.h @@ -8,18 +8,19 @@ /* Copyright (C) 2003,2004, 2005, 2006, 2007 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ #include "libguile/__scm.h" diff --git a/libguile/deprecation.c b/libguile/deprecation.c index 338c47c20..af8b93610 100644 --- a/libguile/deprecation.c +++ b/libguile/deprecation.c @@ -1,18 +1,19 @@ /* Copyright (C) 2001, 2006 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ @@ -41,8 +42,6 @@ -#if (SCM_ENABLE_DEPRECATED == 1) - struct issued_warning { struct issued_warning *prev; const char *message; @@ -138,8 +137,6 @@ print_deprecation_summary (void) } } -#endif /* SCM_ENABLE_DEPRECATED == 1 */ - SCM_DEFINE(scm_include_deprecated_features, "include-deprecated-features", 0, 0, 0, (), @@ -157,7 +154,6 @@ SCM_DEFINE(scm_include_deprecated_features, void scm_init_deprecation () { -#if (SCM_ENABLE_DEPRECATED == 1) const char *level = getenv ("GUILE_WARN_DEPRECATED"); if (level == NULL) level = SCM_WARN_DEPRECATED_DEFAULT; @@ -170,11 +166,11 @@ scm_init_deprecation () SCM_WARN_DEPRECATED = 0; atexit (print_deprecation_summary); } -#endif #include "libguile/deprecation.x" } /* Local Variables: c-file-style: "gnu" - End: */ + End: + */ diff --git a/libguile/deprecation.h b/libguile/deprecation.h index 78853277b..06027c694 100644 --- a/libguile/deprecation.h +++ b/libguile/deprecation.h @@ -3,21 +3,22 @@ #ifndef SCM_DEPRECATION_H #define SCM_DEPRECATION_H -/* Copyright (C) 2001, 2006, 2008 Free Software Foundation, Inc. +/* Copyright (C) 2001, 2006, 2008, 2009 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ @@ -26,20 +27,14 @@ -#if (SCM_ENABLE_DEPRECATED == 1) - -/* These functions are _not_ deprecated, but we exclude them along - with the really deprecated features to be sure that no-one is - trying to emit deprecation warnings when libguile is supposed to be - clean of them. -*/ +/* These functions are a possibly useful part of the API and not only used + internally, thus they are exported always, not depending on + SCM_ENABLE_DEPRECATED. */ SCM_API void scm_c_issue_deprecation_warning (const char *msg); SCM_API void scm_c_issue_deprecation_warning_fmt (const char *msg, ...); SCM_API SCM scm_issue_deprecation_warning (SCM msgs); -#endif - SCM_API SCM scm_include_deprecated_features (void); SCM_INTERNAL void scm_init_deprecation (void); diff --git a/libguile/discouraged.c b/libguile/discouraged.c index 9efd92a00..357cac875 100644 --- a/libguile/discouraged.c +++ b/libguile/discouraged.c @@ -5,18 +5,19 @@ /* Copyright (C) 2003, 2004, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ #ifdef HAVE_CONFIG_H diff --git a/libguile/discouraged.h b/libguile/discouraged.h index 6e537bf1e..1be05f0bc 100644 --- a/libguile/discouraged.h +++ b/libguile/discouraged.h @@ -16,18 +16,19 @@ /* Copyright (C) 2004, 2006 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ #include "libguile/__scm.h" diff --git a/libguile/dynl.c b/libguile/dynl.c index 1326b8bd4..dc98e7d17 100644 --- a/libguile/dynl.c +++ b/libguile/dynl.c @@ -4,18 +4,19 @@ * 2003, 2008, 2009 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/dynl.h b/libguile/dynl.h index 72dc92ea4..eb318ae98 100644 --- a/libguile/dynl.h +++ b/libguile/dynl.h @@ -6,18 +6,19 @@ /* Copyright (C) 1996,1998,2000,2001, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/dynwind.c b/libguile/dynwind.c index 40f94736b..b34f9bef3 100644 --- a/libguile/dynwind.c +++ b/libguile/dynwind.c @@ -1,18 +1,19 @@ /* Copyright (C) 1995,1996,1998,1999,2000,2001, 2003, 2004, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/dynwind.h b/libguile/dynwind.h index dd39dae5a..b178bc429 100644 --- a/libguile/dynwind.h +++ b/libguile/dynwind.h @@ -6,18 +6,19 @@ /* Copyright (C) 1995,1996,1998,1999,2000,2003,2004, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/environments.c b/libguile/environments.c index 78ccd286d..fd4b88300 100644 --- a/libguile/environments.c +++ b/libguile/environments.c @@ -1,18 +1,19 @@ /* Copyright (C) 1999,2000,2001, 2003, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/environments.h b/libguile/environments.h index 2d8765a38..143963254 100644 --- a/libguile/environments.h +++ b/libguile/environments.h @@ -6,18 +6,19 @@ /* Copyright (C) 1999,2000, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/eq.c b/libguile/eq.c index b54a7043a..255c381a0 100644 --- a/libguile/eq.c +++ b/libguile/eq.c @@ -1,18 +1,19 @@ /* Copyright (C) 1995,1996,1997,1998,2000,2001,2003, 2004, 2006 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/eq.h b/libguile/eq.h index af6959fe8..1aeb1c496 100644 --- a/libguile/eq.h +++ b/libguile/eq.h @@ -6,18 +6,19 @@ /* Copyright (C) 1995,1996,2000, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/error.c b/libguile/error.c index e18db9e82..eb513a74a 100644 --- a/libguile/error.c +++ b/libguile/error.c @@ -1,18 +1,19 @@ /* Copyright (C) 1995,1996,1997,1998,2000,2001, 2004, 2006 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/error.h b/libguile/error.h index 042fb4d14..c777a7f44 100644 --- a/libguile/error.h +++ b/libguile/error.h @@ -6,18 +6,19 @@ /* Copyright (C) 1995,1996,1997,1998,2000,2001, 2002, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/eval.c b/libguile/eval.c index a1b352d68..445c61f00 100644 --- a/libguile/eval.c +++ b/libguile/eval.c @@ -2,18 +2,19 @@ * Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ @@ -306,6 +307,9 @@ syntax_error (const char* const msg, const SCM form, const SCM expr) { if (SCM_UNLIKELY (!(cond))) \ syntax_error (message, form, expr); } +static void error_unbound_variable (SCM symbol) SCM_NORETURN; +static void error_defined_variable (SCM symbol) SCM_NORETURN; + /* {Ilocs} @@ -706,6 +710,101 @@ is_system_macro_p (const SCM syntactic_keyword, const SCM form, const SCM env) return 0; } +static SCM +macroexp (SCM x, SCM env) +{ + SCM res, proc, orig_sym; + + /* Don't bother to produce error messages here. We get them when we + eventually execute the code for real. */ + + macro_tail: + orig_sym = SCM_CAR (x); + if (!scm_is_symbol (orig_sym)) + return x; + + { + SCM *proc_ptr = scm_lookupcar1 (x, env, 0); + if (proc_ptr == NULL) + { + /* We have lost the race. */ + goto macro_tail; + } + proc = *proc_ptr; + } + + /* Only handle memoizing macros. `Acros' and `macros' are really + special forms and should not be evaluated here. */ + + if (!SCM_MACROP (proc) + || (SCM_MACRO_TYPE (proc) != 2 && !SCM_BUILTIN_MACRO_P (proc))) + return x; + + SCM_SETCAR (x, orig_sym); /* Undo memoizing effect of lookupcar */ + res = scm_call_2 (SCM_MACRO_CODE (proc), x, env); + + if (scm_ilength (res) <= 0) + /* Result of expansion is not a list. */ + return (scm_list_2 (SCM_IM_BEGIN, res)); + else + { + /* njrev: Several queries here: (1) I don't see how it can be + correct that the SCM_SETCAR 2 lines below this comment needs + protection, but the SCM_SETCAR 6 lines above does not, so + something here is probably wrong. (2) macroexp() is now only + used in one place - scm_m_generalized_set_x - whereas all other + macro expansion happens through expand_user_macros. Therefore + (2.1) perhaps macroexp() could be eliminated completely now? + (2.2) Does expand_user_macros need any critical section + protection? */ + + SCM_CRITICAL_SECTION_START; + SCM_SETCAR (x, SCM_CAR (res)); + SCM_SETCDR (x, SCM_CDR (res)); + SCM_CRITICAL_SECTION_END; + + goto macro_tail; + } +} + + +/* Start of the memoizers for the standard R5RS builtin macros. */ + +static SCM scm_m_quote (SCM xorig, SCM env); +static SCM scm_m_begin (SCM xorig, SCM env); +static SCM scm_m_if (SCM xorig, SCM env); +static SCM scm_m_set_x (SCM xorig, SCM env); +static SCM scm_m_and (SCM xorig, SCM env); +static SCM scm_m_or (SCM xorig, SCM env); +static SCM scm_m_case (SCM xorig, SCM env); +static SCM scm_m_cond (SCM xorig, SCM env); +static SCM scm_m_lambda (SCM xorig, SCM env); +static SCM scm_m_letstar (SCM xorig, SCM env); +static SCM scm_m_do (SCM xorig, SCM env); +static SCM scm_m_quasiquote (SCM xorig, SCM env); +static SCM scm_m_delay (SCM xorig, SCM env); +static SCM scm_m_generalized_set_x (SCM xorig, SCM env); +#if 0 /* Futures are disabled, see "futures.h". */ +static SCM scm_m_future (SCM xorig, SCM env); +#endif +static SCM scm_m_define (SCM x, SCM env); +static SCM scm_m_letrec (SCM xorig, SCM env); +static SCM scm_m_let (SCM xorig, SCM env); +static SCM scm_m_at (SCM xorig, SCM env); +static SCM scm_m_atat (SCM xorig, SCM env); +static SCM scm_m_atslot_ref (SCM xorig, SCM env); +static SCM scm_m_atslot_set_x (SCM xorig, SCM env); +static SCM scm_m_apply (SCM xorig, SCM env); +static SCM scm_m_cont (SCM xorig, SCM env); +#if SCM_ENABLE_ELISP +static SCM scm_m_nil_cond (SCM xorig, SCM env); +static SCM scm_m_atfop (SCM xorig, SCM env); +#endif /* SCM_ENABLE_ELISP */ +static SCM scm_m_atbind (SCM xorig, SCM env); +static SCM scm_m_at_call_with_values (SCM xorig, SCM env); +static SCM scm_m_eval_when (SCM xorig, SCM env); + + static void m_expand_body (const SCM forms, const SCM env) { @@ -828,70 +927,10 @@ m_expand_body (const SCM forms, const SCM env) } } -static SCM -macroexp (SCM x, SCM env) -{ - SCM res, proc, orig_sym; - - /* Don't bother to produce error messages here. We get them when we - eventually execute the code for real. */ - - macro_tail: - orig_sym = SCM_CAR (x); - if (!scm_is_symbol (orig_sym)) - return x; - - { - SCM *proc_ptr = scm_lookupcar1 (x, env, 0); - if (proc_ptr == NULL) - { - /* We have lost the race. */ - goto macro_tail; - } - proc = *proc_ptr; - } - - /* Only handle memoizing macros. `Acros' and `macros' are really - special forms and should not be evaluated here. */ - - if (!SCM_MACROP (proc) - || (SCM_MACRO_TYPE (proc) != 2 && !SCM_BUILTIN_MACRO_P (proc))) - return x; - - SCM_SETCAR (x, orig_sym); /* Undo memoizing effect of lookupcar */ - res = scm_call_2 (SCM_MACRO_CODE (proc), x, env); - - if (scm_ilength (res) <= 0) - /* Result of expansion is not a list. */ - return (scm_list_2 (SCM_IM_BEGIN, res)); - else - { - /* njrev: Several queries here: (1) I don't see how it can be - correct that the SCM_SETCAR 2 lines below this comment needs - protection, but the SCM_SETCAR 6 lines above does not, so - something here is probably wrong. (2) macroexp() is now only - used in one place - scm_m_generalized_set_x - whereas all other - macro expansion happens through expand_user_macros. Therefore - (2.1) perhaps macroexp() could be eliminated completely now? - (2.2) Does expand_user_macros need any critical section - protection? */ - - SCM_CRITICAL_SECTION_START; - SCM_SETCAR (x, SCM_CAR (res)); - SCM_SETCDR (x, SCM_CDR (res)); - SCM_CRITICAL_SECTION_END; - - goto macro_tail; - } -} - -/* Start of the memoizers for the standard R5RS builtin macros. */ - - SCM_SYNTAX (s_and, "and", scm_i_makbimacro, scm_m_and); SCM_GLOBAL_SYMBOL (scm_sym_and, s_and); -SCM +static SCM scm_m_and (SCM expr, SCM env SCM_UNUSED) { const SCM cdr_expr = SCM_CDR (expr); @@ -921,7 +960,7 @@ unmemoize_and (const SCM expr, const SCM env) SCM_SYNTAX (s_begin, "begin", scm_i_makbimacro, scm_m_begin); SCM_GLOBAL_SYMBOL (scm_sym_begin, s_begin); -SCM +static SCM scm_m_begin (SCM expr, SCM env SCM_UNUSED) { const SCM cdr_expr = SCM_CDR (expr); @@ -945,7 +984,7 @@ SCM_SYNTAX (s_case, "case", scm_i_makbimacro, scm_m_case); SCM_GLOBAL_SYMBOL (scm_sym_case, s_case); SCM_GLOBAL_SYMBOL (scm_sym_else, "else"); -SCM +static SCM scm_m_case (SCM expr, SCM env) { SCM clauses; @@ -1041,7 +1080,7 @@ SCM_SYNTAX (s_cond, "cond", scm_i_makbimacro, scm_m_cond); SCM_GLOBAL_SYMBOL (scm_sym_cond, s_cond); SCM_GLOBAL_SYMBOL (scm_sym_arrow, "=>"); -SCM +static SCM scm_m_cond (SCM expr, SCM env) { /* Check, whether 'else or '=> is a literal, i. e. not bound to a value. */ @@ -1203,7 +1242,7 @@ canonicalize_define (const SCM expr) operation. However, EXPRESSION _can_ be evaluated before VARIABLE is bound. This means that EXPRESSION won't necessarily be able to assign values to VARIABLE as in `(define foo (begin (set! foo 1) (+ foo 1)))'. */ -SCM +static SCM scm_m_define (SCM expr, SCM env) { ASSERT_SYNTAX (SCM_TOP_LEVEL (env), s_bad_define, expr); @@ -1258,7 +1297,7 @@ SCM_GLOBAL_SYMBOL (scm_sym_delay, s_delay); * (delay ) is transformed into (#@delay '() ), where * the empty list represents the empty parameter list. This representation * allows for easy creation of the closure during evaluation. */ -SCM +static SCM scm_m_delay (SCM expr, SCM env) { const SCM new_expr = memoize_as_thunk_prototype (expr, env); @@ -1301,7 +1340,7 @@ SCM_GLOBAL_SYMBOL(scm_sym_do, s_do); () ... ) ;; missing steps replaced by var */ -SCM +static SCM scm_m_do (SCM expr, SCM env SCM_UNUSED) { SCM variables = SCM_EOL; @@ -1399,7 +1438,7 @@ unmemoize_do (const SCM expr, const SCM env) SCM_SYNTAX (s_if, "if", scm_i_makbimacro, scm_m_if); SCM_GLOBAL_SYMBOL (scm_sym_if, s_if); -SCM +static SCM scm_m_if (SCM expr, SCM env SCM_UNUSED) { const SCM cdr_expr = SCM_CDR (expr); @@ -1449,7 +1488,7 @@ c_improper_memq (SCM obj, SCM list) return scm_is_eq (list, obj); } -SCM +static SCM scm_m_lambda (SCM expr, SCM env SCM_UNUSED) { SCM formals; @@ -1619,7 +1658,7 @@ memoize_named_let (const SCM expr, const SCM env SCM_UNUSED) /* (let ((v1 i1) (v2 i2) ...) body) with variables v1 .. vn and initializers * i1 .. in is transformed to (#@let (vn ... v2 v1) (i1 i2 ...) body). */ -SCM +static SCM scm_m_let (SCM expr, SCM env) { SCM bindings; @@ -1693,7 +1732,7 @@ unmemoize_let (const SCM expr, const SCM env) SCM_SYNTAX(s_letrec, "letrec", scm_i_makbimacro, scm_m_letrec); SCM_GLOBAL_SYMBOL(scm_sym_letrec, s_letrec); -SCM +static SCM scm_m_letrec (SCM expr, SCM env) { SCM bindings; @@ -1744,7 +1783,7 @@ SCM_GLOBAL_SYMBOL (scm_sym_letstar, s_letstar); /* (let* ((v1 i1) (v2 i2) ...) body) with variables v1 .. vn and initializers * i1 .. in is transformed into the form (#@let* (v1 i1 v2 i2 ...) body). */ -SCM +static SCM scm_m_letstar (SCM expr, SCM env SCM_UNUSED) { SCM binding_idx; @@ -1817,7 +1856,7 @@ unmemoize_letstar (const SCM expr, const SCM env) SCM_SYNTAX (s_or, "or", scm_i_makbimacro, scm_m_or); SCM_GLOBAL_SYMBOL (scm_sym_or, s_or); -SCM +static SCM scm_m_or (SCM expr, SCM env SCM_UNUSED) { const SCM cdr_expr = SCM_CDR (expr); @@ -1901,7 +1940,7 @@ iqq (SCM form, SCM env, unsigned long int depth) return form; } -SCM +static SCM scm_m_quasiquote (SCM expr, SCM env) { const SCM cdr_expr = SCM_CDR (expr); @@ -1914,7 +1953,7 @@ scm_m_quasiquote (SCM expr, SCM env) SCM_SYNTAX (s_quote, "quote", scm_i_makbimacro, scm_m_quote); SCM_GLOBAL_SYMBOL (scm_sym_quote, s_quote); -SCM +static SCM scm_m_quote (SCM expr, SCM env SCM_UNUSED) { SCM quotee; @@ -1943,7 +1982,7 @@ SCM_SYNTAX (s_set_x, "set!", scm_i_makbimacro, scm_m_set_x); */ static const char s_set_x[] = "set!"; SCM_GLOBAL_SYMBOL (scm_sym_set_x, s_set_x); -SCM +static SCM scm_m_set_x (SCM expr, SCM env SCM_UNUSED) { SCM variable; @@ -1973,14 +2012,57 @@ unmemoize_set_x (const SCM expr, const SCM env) } + /* Start of the memoizers for non-R5RS builtin macros. */ +SCM_SYNTAX (s_at, "@", scm_makmmacro, scm_m_at); +SCM_GLOBAL_SYMBOL (scm_sym_at, s_at); + +static SCM +scm_m_at (SCM expr, SCM env SCM_UNUSED) +{ + SCM mod, var; + ASSERT_SYNTAX (scm_ilength (expr) == 3, s_bad_expression, expr); + ASSERT_SYNTAX (scm_ilength (scm_cadr (expr)) > 0, s_bad_expression, expr); + ASSERT_SYNTAX (scm_is_symbol (scm_caddr (expr)), s_bad_expression, expr); + + mod = scm_resolve_module (scm_cadr (expr)); + if (scm_is_false (mod)) + error_unbound_variable (expr); + var = scm_module_variable (scm_module_public_interface (mod), scm_caddr (expr)); + if (scm_is_false (var)) + error_unbound_variable (expr); + + return var; +} + +SCM_SYNTAX (s_atat, "@@", scm_makmmacro, scm_m_atat); +SCM_GLOBAL_SYMBOL (scm_sym_atat, s_atat); + +static SCM +scm_m_atat (SCM expr, SCM env SCM_UNUSED) +{ + SCM mod, var; + ASSERT_SYNTAX (scm_ilength (expr) == 3, s_bad_expression, expr); + ASSERT_SYNTAX (scm_ilength (scm_cadr (expr)) > 0, s_bad_expression, expr); + ASSERT_SYNTAX (scm_is_symbol (scm_caddr (expr)), s_bad_expression, expr); + + mod = scm_resolve_module (scm_cadr (expr)); + if (scm_is_false (mod)) + error_unbound_variable (expr); + var = scm_module_variable (mod, scm_caddr (expr)); + if (scm_is_false (var)) + error_unbound_variable (expr); + + return var; +} + SCM_SYNTAX (s_atapply, "@apply", scm_i_makbimacro, scm_m_apply); SCM_GLOBAL_SYMBOL (scm_sym_atapply, s_atapply); SCM_GLOBAL_SYMBOL (scm_sym_apply, s_atapply + 1); -SCM +static SCM scm_m_apply (SCM expr, SCM env SCM_UNUSED) { const SCM cdr_expr = SCM_CDR (expr); @@ -2017,7 +2099,7 @@ SCM_SYNTAX (s_atbind, "@bind", scm_i_makbimacro, scm_m_atbind); * * FIXME - also implement `@bind*'. */ -SCM +static SCM scm_m_atbind (SCM expr, SCM env) { SCM bindings; @@ -2056,7 +2138,7 @@ scm_m_atbind (SCM expr, SCM env) SCM_SYNTAX(s_atcall_cc, "@call-with-current-continuation", scm_i_makbimacro, scm_m_cont); SCM_GLOBAL_SYMBOL(scm_sym_atcall_cc, s_atcall_cc); -SCM +static SCM scm_m_cont (SCM expr, SCM env SCM_UNUSED) { const SCM cdr_expr = SCM_CDR (expr); @@ -2077,7 +2159,7 @@ unmemoize_atcall_cc (const SCM expr, const SCM env) SCM_SYNTAX (s_at_call_with_values, "@call-with-values", scm_i_makbimacro, scm_m_at_call_with_values); SCM_GLOBAL_SYMBOL(scm_sym_at_call_with_values, s_at_call_with_values); -SCM +static SCM scm_m_at_call_with_values (SCM expr, SCM env SCM_UNUSED) { const SCM cdr_expr = SCM_CDR (expr); @@ -2095,6 +2177,25 @@ unmemoize_at_call_with_values (const SCM expr, const SCM env) unmemoize_exprs (SCM_CDR (expr), env)); } +SCM_SYNTAX (s_eval_when, "eval-when", scm_makmmacro, scm_m_eval_when); +SCM_GLOBAL_SYMBOL (scm_sym_eval_when, s_eval_when); +SCM_SYMBOL (sym_eval, "eval"); +SCM_SYMBOL (sym_load, "load"); + + +static SCM +scm_m_eval_when (SCM expr, SCM env SCM_UNUSED) +{ + ASSERT_SYNTAX (scm_ilength (expr) >= 3, s_bad_expression, expr); + ASSERT_SYNTAX (scm_ilength (scm_cadr (expr)) > 0, s_bad_expression, expr); + + if (scm_is_true (scm_memq (sym_eval, scm_cadr (expr))) + || scm_is_true (scm_memq (sym_load, scm_cadr (expr)))) + return scm_cons (SCM_IM_BEGIN, scm_cddr (expr)); + + return scm_list_1 (SCM_IM_BEGIN); +} + #if 0 /* See futures.h for a comment why futures are not enabled. @@ -2108,7 +2209,7 @@ SCM_GLOBAL_SYMBOL (scm_sym_future, s_future); * (#@future '() ), where the empty list represents the * empty parameter list. This representation allows for easy creation * of the closure during evaluation. */ -SCM +static SCM scm_m_future (SCM expr, SCM env) { const SCM new_expr = memoize_as_thunk_prototype (expr, env); @@ -2128,7 +2229,7 @@ unmemoize_future (const SCM expr, const SCM env) SCM_SYNTAX (s_gset_x, "set!", scm_i_makbimacro, scm_m_generalized_set_x); SCM_SYMBOL (scm_sym_setter, "setter"); -SCM +static SCM scm_m_generalized_set_x (SCM expr, SCM env) { SCM target, exp_target; @@ -2185,9 +2286,11 @@ scm_m_generalized_set_x (SCM expr, SCM env) * arbitrary modules during the startup phase, the code from goops.c should be * moved here. */ +SCM_SYNTAX (s_atslot_ref, "@slot-ref", scm_i_makbimacro, scm_m_atslot_ref); +SCM_SYNTAX (s_atslot_set_x, "@slot-set!", scm_i_makbimacro, scm_m_atslot_set_x); SCM_SYMBOL (sym_atslot_ref, "@slot-ref"); -SCM +static SCM scm_m_atslot_ref (SCM expr, SCM env SCM_UNUSED) { SCM slot_nr; @@ -2220,7 +2323,7 @@ unmemoize_atslot_ref (const SCM expr, const SCM env) SCM_SYMBOL (sym_atslot_set_x, "@slot-set!"); -SCM +static SCM scm_m_atslot_set_x (SCM expr, SCM env SCM_UNUSED) { SCM slot_nr; @@ -2258,7 +2361,7 @@ SCM_SYNTAX (s_nil_cond, "nil-cond", scm_i_makbimacro, scm_m_nil_cond); /* nil-cond expressions have the form * (nil-cond COND VAL COND VAL ... ELSEVAL) */ -SCM +static SCM scm_m_nil_cond (SCM expr, SCM env SCM_UNUSED) { const long length = scm_ilength (SCM_CDR (expr)); @@ -2281,7 +2384,7 @@ SCM_SYNTAX (s_atfop, "@fop", scm_i_makbimacro, scm_m_atfop); * if the value of var (across all aliasing) is not a macro, or * ( ...) * if var is a macro. */ -SCM +static SCM scm_m_atfop (SCM expr, SCM env SCM_UNUSED) { SCM location; @@ -2452,20 +2555,11 @@ scm_i_unmemocopy_body (SCM forms, SCM env) #if (SCM_ENABLE_DEPRECATED == 1) -/* Deprecated in guile 1.7.0 on 2003-11-09. */ -SCM -scm_m_expand_body (SCM exprs, SCM env) -{ - scm_c_issue_deprecation_warning - ("`scm_m_expand_body' is deprecated."); - m_expand_body (exprs, env); - return exprs; -} - +static SCM scm_m_undefine (SCM expr, SCM env); SCM_SYNTAX (s_undefine, "undefine", scm_makacro, scm_m_undefine); -SCM +static SCM scm_m_undefine (SCM expr, SCM env) { SCM variable; @@ -2489,55 +2583,10 @@ scm_m_undefine (SCM expr, SCM env) return SCM_UNSPECIFIED; } -SCM -scm_macroexp (SCM x, SCM env) -{ - scm_c_issue_deprecation_warning - ("`scm_macroexp' is deprecated."); - return macroexp (x, env); -} - -#endif +#endif /* SCM_ENABLE_DEPRECATED */ -#if (SCM_ENABLE_DEPRECATED == 1) - -SCM -scm_unmemocar (SCM form, SCM env) -{ - scm_c_issue_deprecation_warning - ("`scm_unmemocar' is deprecated."); - - if (!scm_is_pair (form)) - return form; - else - { - SCM c = SCM_CAR (form); - if (SCM_VARIABLEP (c)) - { - SCM sym = scm_module_reverse_lookup (scm_env_module (env), c); - if (scm_is_false (sym)) - sym = sym_three_question_marks; - SCM_SETCAR (form, sym); - } - else if (SCM_ILOCP (c)) - { - unsigned long int ir; - - for (ir = SCM_IFRAME (c); ir != 0; --ir) - env = SCM_CDR (env); - env = SCM_CAAR (env); - for (ir = SCM_IDIST (c); ir != 0; --ir) - env = SCM_CDR (env); - - SCM_SETCAR (form, SCM_ICDRP (c) ? env : SCM_CAR (env)); - } - return form; - } -} - -#endif - + /*****************************************************************************/ /*****************************************************************************/ /* The definitions for execution start here. */ @@ -2662,9 +2711,6 @@ scm_ilookup (SCM iloc, SCM env) SCM_SYMBOL (scm_unbound_variable_key, "unbound-variable"); -static void error_unbound_variable (SCM symbol) SCM_NORETURN; -static void error_defined_variable (SCM symbol) SCM_NORETURN; - /* Call this for variables that are unfound. */ static void @@ -2967,8 +3013,19 @@ scm_t_option scm_debug_opts[] = { { SCM_OPTION_INTEGER, "depth", 20, "Maximal length of printed backtrace." }, { SCM_OPTION_BOOLEAN, "backtrace", 0, "Show backtrace on error." }, { SCM_OPTION_BOOLEAN, "debug", 0, "Use the debugging evaluator." }, + /* This default stack limit will be overridden by debug.c:init_stack_limit(), + if we have getrlimit() and the stack limit is not INFINITY. But it is still + important, as some systems have both the soft and the hard limits set to + INFINITY; in that case we fall back to this value. - { SCM_OPTION_INTEGER, "stack", 40000, "Stack size limit (measured in words; 0 = no check)." }, + The situation is aggravated by certain compilers, which can consume + "beaucoup de stack", as they say in France. + + See http://thread.gmane.org/gmane.lisp.guile.devel/8599/focus=8662 for + more discussion. This setting is 640 KB on 32-bit arches (should be enough + for anyone!) or a whoppin' 1280 KB on 64-bit arches. + */ + { SCM_OPTION_INTEGER, "stack", 160000, "Stack size limit (measured in words; 0 = no check)." }, { SCM_OPTION_SCM, "show-file-name", (unsigned long)SCM_BOOL_T, "Show file names and line numbers " "in backtraces when not `#f'. A value of `base' " @@ -3324,7 +3381,7 @@ call_dsubr_1 (SCM proc, SCM arg1) return (scm_from_double (SCM_DSUBRF (proc) (scm_i_fraction2double (arg1)))); } SCM_WTA_DISPATCH_1 (*SCM_SUBR_GENERIC (proc), arg1, - SCM_ARG1, scm_i_symbol_chars (SCM_SNAME (proc))); + SCM_ARG1, scm_i_symbol_chars (SCM_SUBR_NAME (proc))); } static SCM @@ -4056,11 +4113,12 @@ SCM_DEFINE (scm_eval, "eval", 2, 0, 0, scm_dynwind_begin (SCM_F_DYNWIND_REWINDABLE); if (scm_is_dynamic_state (module_or_state)) scm_dynwind_current_dynamic_state (module_or_state); - else + else if (scm_module_system_booted_p) { SCM_VALIDATE_MODULE (2, module_or_state); scm_dynwind_current_module (module_or_state); } + /* otherwise if the module system isn't booted, ignore the module arg */ res = scm_primitive_eval (exp); diff --git a/libguile/eval.h b/libguile/eval.h index 333265263..4467358f5 100644 --- a/libguile/eval.h +++ b/libguile/eval.h @@ -3,22 +3,23 @@ #ifndef SCM_EVAL_H #define SCM_EVAL_H -/* Copyright (C) 1995,1996,1998,1999,2000,2001,2002,2003,2004,2008 +/* Copyright (C) 1995,1996,1998,1999,2000,2001,2002,2003,2004,2008,2009 * Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ @@ -94,10 +95,13 @@ SCM_API SCM scm_sym_quasiquote; SCM_API SCM scm_sym_unquote; SCM_API SCM scm_sym_uq_splicing; +SCM_API SCM scm_sym_at; +SCM_API SCM scm_sym_atat; SCM_API SCM scm_sym_atapply; SCM_API SCM scm_sym_atcall_cc; SCM_API SCM scm_sym_at_call_with_values; SCM_API SCM scm_sym_delay; +SCM_API SCM scm_sym_eval_when; SCM_API SCM scm_sym_arrow; SCM_API SCM scm_sym_else; SCM_API SCM scm_sym_apply; @@ -111,37 +115,6 @@ SCM_API SCM * scm_lookupcar (SCM vloc, SCM genv, int check); SCM_API SCM scm_eval_car (SCM pair, SCM env); SCM_API SCM scm_eval_body (SCM code, SCM env); SCM_API SCM scm_eval_args (SCM i, SCM env, SCM proc); -SCM_API SCM scm_m_quote (SCM xorig, SCM env); -SCM_API SCM scm_m_begin (SCM xorig, SCM env); -SCM_API SCM scm_m_if (SCM xorig, SCM env); -SCM_API SCM scm_m_set_x (SCM xorig, SCM env); -SCM_API SCM scm_m_vref (SCM xorig, SCM env); -SCM_API SCM scm_m_vset (SCM xorig, SCM env); -SCM_API SCM scm_m_and (SCM xorig, SCM env); -SCM_API SCM scm_m_or (SCM xorig, SCM env); -SCM_API SCM scm_m_case (SCM xorig, SCM env); -SCM_API SCM scm_m_cond (SCM xorig, SCM env); -SCM_API SCM scm_m_lambda (SCM xorig, SCM env); -SCM_API SCM scm_m_letstar (SCM xorig, SCM env); -SCM_API SCM scm_m_do (SCM xorig, SCM env); -SCM_API SCM scm_m_quasiquote (SCM xorig, SCM env); -SCM_API SCM scm_m_delay (SCM xorig, SCM env); -SCM_API SCM scm_m_generalized_set_x (SCM xorig, SCM env); -SCM_API SCM scm_m_future (SCM xorig, SCM env); -SCM_API SCM scm_m_define (SCM x, SCM env); -SCM_API SCM scm_m_letrec (SCM xorig, SCM env); -SCM_API SCM scm_m_let (SCM xorig, SCM env); -SCM_API SCM scm_m_apply (SCM xorig, SCM env); -SCM_API SCM scm_m_cont (SCM xorig, SCM env); -#if SCM_ENABLE_ELISP -SCM_API SCM scm_m_nil_cond (SCM xorig, SCM env); -SCM_API SCM scm_m_atfop (SCM xorig, SCM env); -#endif /* SCM_ENABLE_ELISP */ -SCM_API SCM scm_m_atbind (SCM xorig, SCM env); -SCM_API SCM scm_m_atslot_ref (SCM xorig, SCM env); -SCM_API SCM scm_m_atslot_set_x (SCM xorig, SCM env); -SCM_API SCM scm_m_atdispatch (SCM xorig, SCM env); -SCM_API SCM scm_m_at_call_with_values (SCM xorig, SCM env); SCM_API int scm_badargsp (SCM formals, SCM args); SCM_API SCM scm_call_0 (SCM proc); SCM_API SCM scm_call_1 (SCM proc, SCM arg1); @@ -183,15 +156,6 @@ SCM_INTERNAL void scm_init_eval (void); #if (SCM_ENABLE_DEPRECATED == 1) -SCM_API SCM scm_m_undefine (SCM x, SCM env); - -/* Deprecated in guile 1.7.0 on 2003-11-09. */ -SCM_API SCM scm_m_expand_body (SCM xorig, SCM env); - -/* Deprecated in guile 1.7.0 on 2003-11-16. */ -SCM_API SCM scm_unmemocar (SCM form, SCM env); -SCM_API SCM scm_macroexp (SCM x, SCM env); - /* Deprecated in guile 1.7.0 on 2004-03-29. */ SCM_API SCM scm_ceval (SCM x, SCM env); SCM_API SCM scm_deval (SCM x, SCM env); diff --git a/libguile/eval.i.c b/libguile/eval.i.c index 573a7b5fb..99aa265de 100644 --- a/libguile/eval.i.c +++ b/libguile/eval.i.c @@ -4,18 +4,19 @@ * Copyright (C) 2002, 03, 04, 05, 06, 07, 09 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ #undef RETURN @@ -1237,7 +1238,7 @@ dispatch: } SCM_WTA_DISPATCH_1 (*SCM_SUBR_GENERIC (proc), arg1, SCM_ARG1, - scm_i_symbol_chars (SCM_SNAME (proc))); + scm_i_symbol_chars (SCM_SUBR_NAME (proc))); case scm_tc7_cxr: RETURN (scm_i_chase_pairs (arg1, (scm_t_bits) SCM_SUBRF (proc))); case scm_tc7_rpsubr: @@ -1764,7 +1765,7 @@ tail: RETURN (scm_from_double (SCM_DSUBRF (proc) (scm_i_fraction2double (arg1)))); } SCM_WTA_DISPATCH_1 (*SCM_SUBR_GENERIC (proc), arg1, - SCM_ARG1, scm_i_symbol_chars (SCM_SNAME (proc))); + SCM_ARG1, scm_i_symbol_chars (SCM_SUBR_NAME (proc))); case scm_tc7_cxr: if (SCM_UNLIKELY (SCM_UNBNDP (arg1) || !scm_is_null (args))) scm_wrong_num_args (proc); diff --git a/libguile/evalext.c b/libguile/evalext.c index 5ca78066d..19d8f2e02 100644 --- a/libguile/evalext.c +++ b/libguile/evalext.c @@ -1,18 +1,19 @@ /* Copyright (C) 1998,1999,2000,2001,2002,2003, 2006, 2008, 2009 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ @@ -30,49 +31,23 @@ #include "libguile/evalext.h" SCM_DEFINE (scm_defined_p, "defined?", 1, 1, 0, - (SCM sym, SCM env), - "Return @code{#t} if @var{sym} is defined in the lexical " - "environment @var{env}. When @var{env} is not specified, " - "look in the top-level environment as defined by the " - "current module.") + (SCM sym, SCM module), + "Return @code{#t} if @var{sym} is defined in the module " + "@var{module} or the current module when @var{module} is not" + "specified.") #define FUNC_NAME s_scm_defined_p { SCM var; SCM_VALIDATE_SYMBOL (1, sym); - if (SCM_UNBNDP (env)) - var = scm_sym2var (sym, scm_current_module_lookup_closure (), - SCM_BOOL_F); + if (SCM_UNBNDP (module)) + module = scm_current_module (); else - { - SCM frames = env; - register SCM b; - for (; SCM_NIMP (frames); frames = SCM_CDR (frames)) - { - SCM_ASSERT (scm_is_pair (frames), env, SCM_ARG2, FUNC_NAME); - b = SCM_CAR (frames); - if (scm_is_true (scm_procedure_p (b))) - break; - SCM_ASSERT (scm_is_pair (b), env, SCM_ARG2, FUNC_NAME); - for (b = SCM_CAR (b); SCM_NIMP (b); b = SCM_CDR (b)) - { - if (!scm_is_pair (b)) - { - if (scm_is_eq (b, sym)) - return SCM_BOOL_T; - else - break; - } - if (scm_is_eq (SCM_CAR (b), sym)) - return SCM_BOOL_T; - } - } - var = scm_sym2var (sym, - SCM_NIMP (frames) ? SCM_CAR (frames) : SCM_BOOL_F, - SCM_BOOL_F); - } - + SCM_VALIDATE_MODULE (2, module); + + var = scm_module_variable (module, sym); + return (scm_is_false (var) || SCM_UNBNDP (SCM_VARIABLE_REF (var)) ? SCM_BOOL_F : SCM_BOOL_T); diff --git a/libguile/evalext.h b/libguile/evalext.h index a6a4a9fdc..fc3f1e617 100644 --- a/libguile/evalext.h +++ b/libguile/evalext.h @@ -6,18 +6,19 @@ /* Copyright (C) 1998,1999,2000, 2003, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/extensions.c b/libguile/extensions.c index 1090b8bd5..54351dd9c 100644 --- a/libguile/extensions.c +++ b/libguile/extensions.c @@ -3,18 +3,19 @@ * Copyright (C) 2001, 2006 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ #ifdef HAVE_CONFIG_H @@ -76,6 +77,7 @@ load_extension (SCM lib, SCM init) { extension_t *ext; char *clib, *cinit; + int found = 0; scm_dynwind_begin (0); @@ -89,10 +91,14 @@ load_extension (SCM lib, SCM init) && !strcmp (ext->init, cinit)) { ext->func (ext->data); + found = 1; break; } scm_dynwind_end (); + + if (found) + return; } /* Dynamically link the library. */ diff --git a/libguile/extensions.h b/libguile/extensions.h index 596b43ae0..765f9bee1 100644 --- a/libguile/extensions.h +++ b/libguile/extensions.h @@ -6,18 +6,19 @@ /* Copyright (C) 2001, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ @@ -26,6 +27,8 @@ +typedef void (*scm_t_extension_init_func)(void*); + SCM_API void scm_c_register_extension (const char *lib, const char *init, void (*func) (void *), void *data); diff --git a/libguile/feature.c b/libguile/feature.c index 8283cd6f5..9ef4b658e 100644 --- a/libguile/feature.c +++ b/libguile/feature.c @@ -1,18 +1,19 @@ /* Copyright (C) 1995,1996,1998,1999,2000,2001,2002, 2003, 2004, 2006, 2007 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/feature.h b/libguile/feature.h index 8c6371e94..d373bc773 100644 --- a/libguile/feature.h +++ b/libguile/feature.h @@ -6,18 +6,19 @@ /* Copyright (C) 1995,1996,1999,2000,2001, 2006, 2007, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/filesys.c b/libguile/filesys.c index ec33328b1..a2db6996f 100644 --- a/libguile/filesys.c +++ b/libguile/filesys.c @@ -1,18 +1,19 @@ /* Copyright (C) 1996,1997,1998,1999,2000,2001, 2002, 2004, 2006 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ @@ -29,6 +30,7 @@ #endif #include +#include #include #include @@ -580,17 +582,23 @@ static int fstat_Win32 (int fdes, struct stat *buf) } #endif /* __MINGW32__ */ -SCM_DEFINE (scm_stat, "stat", 1, 0, 0, - (SCM object), +SCM_DEFINE (scm_stat, "stat", 1, 1, 0, + (SCM object, SCM exception_on_error), "Return an object containing various information about the file\n" "determined by @var{obj}. @var{obj} can be a string containing\n" "a file name or a port or integer file descriptor which is open\n" "on a file (in which case @code{fstat} is used as the underlying\n" "system call).\n" "\n" - "The object returned by @code{stat} can be passed as a single\n" - "parameter to the following procedures, all of which return\n" - "integers:\n" + "If the optional @var{exception_on_error} argument is true, which\n" + "is the default, an exception will be raised if the underlying\n" + "system call returns an error, for example if the file is not\n" + "found or is not readable. Otherwise, an error will cause\n" + "@code{stat} to return @code{#f}." + "\n" + "The object returned by a successful call to @code{stat} can be\n" + "passed as a single parameter to the following procedures, all of\n" + "which return integers:\n" "\n" "@table @code\n" "@item stat:dev\n" @@ -678,12 +686,16 @@ SCM_DEFINE (scm_stat, "stat", 1, 0, 0, if (rv == -1) { - int en = errno; - - SCM_SYSERROR_MSG ("~A: ~S", - scm_list_2 (scm_strerror (scm_from_int (en)), - object), - en); + if (SCM_UNBNDP (exception_on_error) || scm_is_true (exception_on_error)) + { + int en = errno; + SCM_SYSERROR_MSG ("~A: ~S", + scm_list_2 (scm_strerror (scm_from_int (en)), + object), + en); + } + else + return SCM_BOOL_F; } return scm_stat2scm (&stat_temp); } @@ -1650,6 +1662,27 @@ SCM_DEFINE (scm_basename, "basename", 1, 1, 0, } #undef FUNC_NAME +SCM_DEFINE (scm_canonicalize_path, "canonicalize-path", 1, 0, 0, + (SCM path), + "Return the canonical path of @var{path}. A canonical path has\n" + "no @code{.} or @code{..} components, nor any repeated path\n" + "separators (@code{/}) nor symlinks.\n\n" + "Raises an error if any component of @var{path} does not exist.") +#define FUNC_NAME s_scm_canonicalize_path +{ char *str, *canon; + + SCM_VALIDATE_STRING (1, path); + + str = scm_to_locale_string (path); + canon = canonicalize_file_name (str); + free (str); + + if (canon) + return scm_take_locale_string (canon); + else + SCM_SYSERROR; +} +#undef FUNC_NAME diff --git a/libguile/filesys.h b/libguile/filesys.h index a38a5b594..b9a6ca8a6 100644 --- a/libguile/filesys.h +++ b/libguile/filesys.h @@ -6,18 +6,19 @@ /* Copyright (C) 1995,1997,1998,1999,2000,2001, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ @@ -42,7 +43,7 @@ SCM_API SCM scm_open_fdes (SCM path, SCM flags, SCM mode); SCM_API SCM scm_open (SCM path, SCM flags, SCM mode); SCM_API SCM scm_close (SCM fd_or_port); SCM_API SCM scm_close_fdes (SCM fd); -SCM_API SCM scm_stat (SCM object); +SCM_API SCM scm_stat (SCM object, SCM exception_on_error); SCM_API SCM scm_link (SCM oldpath, SCM newpath); SCM_API SCM scm_rename (SCM oldname, SCM newname); SCM_API SCM scm_delete_file (SCM str); @@ -64,6 +65,7 @@ SCM_API SCM scm_lstat (SCM str); SCM_API SCM scm_copy_file (SCM oldfile, SCM newfile); SCM_API SCM scm_dirname (SCM filename); SCM_API SCM scm_basename (SCM filename, SCM suffix); +SCM_API SCM scm_canonicalize_path (SCM path); SCM_INTERNAL void scm_init_filesys (void); diff --git a/libguile/fluids.c b/libguile/fluids.c index 02eff9f20..75dcccf75 100644 --- a/libguile/fluids.c +++ b/libguile/fluids.c @@ -1,18 +1,19 @@ /* Copyright (C) 1996,1997,2000,2001, 2004, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ #ifdef HAVE_CONFIG_H diff --git a/libguile/fluids.h b/libguile/fluids.h index c88ffa88f..2bfcce52f 100644 --- a/libguile/fluids.h +++ b/libguile/fluids.h @@ -6,18 +6,19 @@ /* Copyright (C) 1996,2000,2001, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/fports.c b/libguile/fports.c index ab4538028..00a727870 100644 --- a/libguile/fports.c +++ b/libguile/fports.c @@ -1,18 +1,19 @@ -/* Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2002, 2003, 2004, 2006, 2007, 2008 Free Software Foundation, Inc. +/* Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ @@ -616,8 +617,8 @@ fport_fill_input (SCM port) } } -static off_t_or_off64_t -fport_seek_or_seek64 (SCM port, off_t_or_off64_t offset, int whence) +static scm_t_off +fport_seek (SCM port, scm_t_off offset, int whence) { scm_t_port *pt = SCM_PTAB_ENTRY (port); scm_t_fport *fp = SCM_FSTREAM (port); @@ -668,41 +669,8 @@ fport_seek_or_seek64 (SCM port, off_t_or_off64_t offset, int whence) return result; } -/* If we've got largefile and off_t isn't already off64_t then - fport_seek_or_seek64 needs a range checking wrapper to be fport_seek in - the port descriptor. - - Otherwise if no largefile, or off_t is the same as off64_t (which is the - case on NetBSD apparently), then fport_seek_or_seek64 is right to be - fport_seek already. */ - -#if GUILE_USE_64_CALLS && HAVE_STAT64 && SIZEOF_OFF_T != SIZEOF_OFF64_T -static off_t -fport_seek (SCM port, off_t offset, int whence) -{ - off64_t rv = fport_seek_or_seek64 (port, (off64_t) offset, whence); - if (rv > OFF_T_MAX || rv < OFF_T_MIN) - { - errno = EOVERFLOW; - scm_syserror ("fport_seek"); - } - return (off_t) rv; - -} -#else -#define fport_seek fport_seek_or_seek64 -#endif - -/* `how' has been validated and is one of SEEK_SET, SEEK_CUR or SEEK_END */ -SCM -scm_i_fport_seek (SCM port, SCM offset, int how) -{ - return scm_from_off_t_or_off64_t - (fport_seek_or_seek64 (port, scm_to_off_t_or_off64_t (offset), how)); -} - static void -fport_truncate (SCM port, off_t length) +fport_truncate (SCM port, scm_t_off length) { scm_t_fport *fp = SCM_FSTREAM (port); @@ -710,13 +678,6 @@ fport_truncate (SCM port, off_t length) scm_syserror ("ftruncate"); } -int -scm_i_fport_truncate (SCM port, SCM length) -{ - scm_t_fport *fp = SCM_FSTREAM (port); - return ftruncate_or_ftruncate64 (fp->fdes, scm_to_off_t_or_off64_t (length)); -} - /* helper for fport_write: try to write data, using multiple system calls if required. */ #define FUNC_NAME "write_all" @@ -754,7 +715,7 @@ fport_write (SCM port, const void *data, size_t size) } { - off_t space = pt->write_end - pt->write_pos; + scm_t_off space = pt->write_end - pt->write_pos; if (size <= space) { diff --git a/libguile/fports.h b/libguile/fports.h index c737b1eaa..cbef0f8ec 100644 --- a/libguile/fports.h +++ b/libguile/fports.h @@ -3,21 +3,22 @@ #ifndef SCM_FPORTS_H #define SCM_FPORTS_H -/* Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2006, 2008 Free Software Foundation, Inc. +/* Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2006, 2008, 2009 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ @@ -58,8 +59,6 @@ SCM_INTERNAL void scm_init_fports (void); /* internal functions */ SCM_INTERNAL SCM scm_i_fdes_to_port (int fdes, long mode_bits, SCM name); -SCM_INTERNAL int scm_i_fport_truncate (SCM, SCM); -SCM_INTERNAL SCM scm_i_fport_seek (SCM, SCM, int); #endif /* SCM_FPORTS_H */ diff --git a/libguile/frames.c b/libguile/frames.c index 3452caf5c..caa95f7d9 100644 --- a/libguile/frames.c +++ b/libguile/frames.c @@ -1,49 +1,28 @@ -/* Copyright (C) 2001 Free Software Foundation, Inc. - * - * 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 2, or (at your option) - * any later version. +/* Copyright (C) 2001, 2009 Free Software Foundation, Inc. * - * 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 software; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307 USA + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * As a special exception, the Free Software Foundation gives permission - * for additional uses of the text contained in its release of GUILE. + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * The exception is that, if you link the GUILE library with other files - * to produce an executable, this does not by itself cause the - * resulting executable to be covered by the GNU General Public License. - * Your use of that executable is in no way restricted on account of - * linking the GUILE library code into it. - * - * This exception does not however invalidate any other reasons why - * the executable file might be covered by the GNU General Public License. - * - * This exception applies only to the code released by the - * Free Software Foundation under the name GUILE. If you copy - * code from other Free Software Foundation releases into a copy of - * GUILE, as the General Public License permits, the exception does - * not apply to the code that you add in this way. To avoid misleading - * anyone as to the status of such modified files, you must delete - * this exception notice from them. - * - * If you write modifications of your own for GUILE, it is your choice - * whether to permit this exception to apply to your modifications. - * If you do not wish that, delete this exception notice. */ + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ #if HAVE_CONFIG_H # include #endif +#include #include +#include "_scm.h" #include "vm-bootstrap.h" #include "frames.h" @@ -230,16 +209,6 @@ SCM_DEFINE (scm_vm_frame_dynamic_link, "vm-frame-dynamic-link", 1, 0, 0, } #undef FUNC_NAME -SCM_DEFINE (scm_vm_frame_external_link, "vm-frame-external-link", 1, 0, 0, - (SCM frame), - "") -#define FUNC_NAME s_scm_vm_frame_external_link -{ - SCM_VALIDATE_VM_FRAME (1, frame); - return SCM_FRAME_EXTERNAL_LINK (SCM_VM_FRAME_FP (frame)); -} -#undef FUNC_NAME - SCM_DEFINE (scm_vm_frame_stack, "vm-frame-stack", 1, 0, 0, (SCM frame), "") @@ -282,6 +251,8 @@ scm_bootstrap_frames (void) { scm_tc16_vm_frame = scm_make_smob_type ("vm-frame", 0); scm_set_smob_print (scm_tc16_vm_frame, vm_frame_print); + scm_c_register_extension ("libguile", "scm_init_frames", + (scm_t_extension_init_func)scm_init_frames, NULL); } void diff --git a/libguile/frames.h b/libguile/frames.h index 836763700..1b3153a3e 100644 --- a/libguile/frames.h +++ b/libguile/frames.h @@ -1,43 +1,20 @@ -/* Copyright (C) 2001 Free Software Foundation, Inc. +/* Copyright (C) 2001, 2009 Free Software Foundation, Inc. + * * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * 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 2, 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 software; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307 USA + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * As a special exception, the Free Software Foundation gives permission - * for additional uses of the text contained in its release of GUILE. - * - * The exception is that, if you link the GUILE library with other files - * to produce an executable, this does not by itself cause the - * resulting executable to be covered by the GNU General Public License. - * Your use of that executable is in no way restricted on account of - * linking the GUILE library code into it. - * - * This exception does not however invalidate any other reasons why - * the executable file might be covered by the GNU General Public License. - * - * This exception applies only to the code released by the - * Free Software Foundation under the name GUILE. If you copy - * code from other Free Software Foundation releases into a copy of - * GUILE, as the General Public License permits, the exception does - * not apply to the code that you add in this way. To avoid misleading - * anyone as to the status of such modified files, you must delete - * this exception notice from them. - * - * If you write modifications of your own for GUILE, it is your choice - * whether to permit this exception to apply to your modifications. - * If you do not wish that, delete this exception notice. */ + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ #ifndef _SCM_FRAMES_H_ #define _SCM_FRAMES_H_ @@ -53,12 +30,11 @@ /* VM Frame Layout --------------- - | | <- fp + bp->nargs + bp->nlocs + 4 + | | <- fp + bp->nargs + bp->nlocs + 3 +------------------+ = SCM_FRAME_UPPER_ADDRESS (fp) | Return address | | MV return address| - | Dynamic link | - | External link | <- fp + bp->nargs + bp->nlocs + | Dynamic link | <- fp + bp->nargs + bp->blocs | Local variable 1 | = SCM_FRAME_DATA_ADDRESS (fp) | Local variable 0 | <- fp + bp->nargs | Argument 1 | @@ -74,21 +50,20 @@ #define SCM_FRAME_DATA_ADDRESS(fp) \ (fp + SCM_PROGRAM_DATA (SCM_FRAME_PROGRAM (fp))->nargs \ + SCM_PROGRAM_DATA (SCM_FRAME_PROGRAM (fp))->nlocs) -#define SCM_FRAME_UPPER_ADDRESS(fp) (SCM_FRAME_DATA_ADDRESS (fp) + 4) +#define SCM_FRAME_UPPER_ADDRESS(fp) (SCM_FRAME_DATA_ADDRESS (fp) + 3) #define SCM_FRAME_LOWER_ADDRESS(fp) (fp - 1) #define SCM_FRAME_BYTE_CAST(x) ((scm_byte_t *) SCM_UNPACK (x)) #define SCM_FRAME_STACK_CAST(x) ((SCM *) SCM_UNPACK (x)) #define SCM_FRAME_RETURN_ADDRESS(fp) \ - (SCM_FRAME_BYTE_CAST (SCM_FRAME_DATA_ADDRESS (fp)[3])) -#define SCM_FRAME_MV_RETURN_ADDRESS(fp) \ (SCM_FRAME_BYTE_CAST (SCM_FRAME_DATA_ADDRESS (fp)[2])) +#define SCM_FRAME_MV_RETURN_ADDRESS(fp) \ + (SCM_FRAME_BYTE_CAST (SCM_FRAME_DATA_ADDRESS (fp)[1])) #define SCM_FRAME_DYNAMIC_LINK(fp) \ - (SCM_FRAME_STACK_CAST (SCM_FRAME_DATA_ADDRESS (fp)[1])) + (SCM_FRAME_STACK_CAST (SCM_FRAME_DATA_ADDRESS (fp)[0])) #define SCM_FRAME_SET_DYNAMIC_LINK(fp, dl) \ - ((SCM_FRAME_DATA_ADDRESS (fp)[1])) = (SCM)(dl); -#define SCM_FRAME_EXTERNAL_LINK(fp) (SCM_FRAME_DATA_ADDRESS (fp)[0]) + ((SCM_FRAME_DATA_ADDRESS (fp)[0])) = (SCM)(dl); #define SCM_FRAME_VARIABLE(fp,i) fp[i] #define SCM_FRAME_PROGRAM(fp) fp[-1] @@ -97,7 +72,7 @@ * Heap frames */ -extern scm_t_bits scm_tc16_vm_frame; +SCM_API scm_t_bits scm_tc16_vm_frame; struct scm_vm_frame { @@ -118,24 +93,23 @@ struct scm_vm_frame #define SCM_VALIDATE_VM_FRAME(p,x) SCM_MAKE_VALIDATE (p, x, VM_FRAME_P) /* FIXME rename scm_byte_t */ -extern SCM scm_c_make_vm_frame (SCM stack_holder, SCM *fp, SCM *sp, +SCM_API SCM scm_c_make_vm_frame (SCM stack_holder, SCM *fp, SCM *sp, scm_byte_t *ip, scm_t_ptrdiff offset); -extern SCM scm_vm_frame_p (SCM obj); -extern SCM scm_vm_frame_program (SCM frame); -extern SCM scm_vm_frame_arguments (SCM frame); -extern SCM scm_vm_frame_source (SCM frame); -extern SCM scm_vm_frame_local_ref (SCM frame, SCM index); -extern SCM scm_vm_frame_local_set_x (SCM frame, SCM index, SCM val); -extern SCM scm_vm_frame_return_address (SCM frame); -extern SCM scm_vm_frame_mv_return_address (SCM frame); -extern SCM scm_vm_frame_dynamic_link (SCM frame); -extern SCM scm_vm_frame_external_link (SCM frame); -extern SCM scm_vm_frame_stack (SCM frame); +SCM_API SCM scm_vm_frame_p (SCM obj); +SCM_API SCM scm_vm_frame_program (SCM frame); +SCM_API SCM scm_vm_frame_arguments (SCM frame); +SCM_API SCM scm_vm_frame_source (SCM frame); +SCM_API SCM scm_vm_frame_local_ref (SCM frame, SCM index); +SCM_API SCM scm_vm_frame_local_set_x (SCM frame, SCM index, SCM val); +SCM_API SCM scm_vm_frame_return_address (SCM frame); +SCM_API SCM scm_vm_frame_mv_return_address (SCM frame); +SCM_API SCM scm_vm_frame_dynamic_link (SCM frame); +SCM_API SCM scm_vm_frame_stack (SCM frame); -extern SCM scm_c_vm_frame_prev (SCM frame); +SCM_API SCM scm_c_vm_frame_prev (SCM frame); -extern void scm_bootstrap_frames (void); -extern void scm_init_frames (void); +SCM_INTERNAL void scm_bootstrap_frames (void); +SCM_INTERNAL void scm_init_frames (void); #endif /* _SCM_FRAMES_H_ */ diff --git a/libguile/futures.c b/libguile/futures.c index 1bba960b3..b330f4ded 100644 --- a/libguile/futures.c +++ b/libguile/futures.c @@ -1,18 +1,19 @@ /* Copyright (C) 1995,1996,1997,1998,2000,2001, 2002, 2003, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/futures.h b/libguile/futures.h index 95916f33b..5d7712e1a 100644 --- a/libguile/futures.h +++ b/libguile/futures.h @@ -6,18 +6,19 @@ /* Copyright (C) 2002, 2003, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/gc-malloc.c b/libguile/gc-malloc.c index 6839ba832..19d68781a 100644 --- a/libguile/gc-malloc.c +++ b/libguile/gc-malloc.c @@ -1,18 +1,19 @@ /* Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2002, 2003, 2004, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/gc-segment-table.c b/libguile/gc-segment-table.c index 3e92c8c5c..75d109c85 100644 --- a/libguile/gc-segment-table.c +++ b/libguile/gc-segment-table.c @@ -1,18 +1,19 @@ /* Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2002, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ #ifdef HAVE_CONFIG_H diff --git a/libguile/gc.c b/libguile/gc.c index 8020c2180..cef9b3f6f 100644 --- a/libguile/gc.c +++ b/libguile/gc.c @@ -1,18 +1,19 @@ /* Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2002, 2003, 2006, 2008, 2009 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ /* #define DEBUGINFO */ diff --git a/libguile/gc.h b/libguile/gc.h index 3603ff7ef..e886bec4b 100644 --- a/libguile/gc.h +++ b/libguile/gc.h @@ -6,18 +6,19 @@ /* Copyright (C) 1995,1996,1998,1999,2000,2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/gdb_interface.h b/libguile/gdb_interface.h index 5be4d0786..2278fc2c2 100644 --- a/libguile/gdb_interface.h +++ b/libguile/gdb_interface.h @@ -5,19 +5,20 @@ /* Simple interpreter interface for GDB, the GNU debugger. Copyright (C) 1996, 2000, 2001, 2006 Free Software Foundation - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA The author can be reached at djurfeldt@nada.kth.se Mikael Djurfeldt, SANS/NADA KTH, 10044 STOCKHOLM, SWEDEN */ diff --git a/libguile/gdbint.c b/libguile/gdbint.c index 4ec9ad48c..0d55e7de4 100644 --- a/libguile/gdbint.c +++ b/libguile/gdbint.c @@ -3,18 +3,19 @@ * Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ #ifdef HAVE_CONFIG_H diff --git a/libguile/gdbint.h b/libguile/gdbint.h index 64b9559c9..d7c6cf31e 100644 --- a/libguile/gdbint.h +++ b/libguile/gdbint.h @@ -6,18 +6,19 @@ /* Copyright (C) 1996,2000, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/gen-scmconfig.c b/libguile/gen-scmconfig.c index 85ebfaed7..0e897ca8c 100644 --- a/libguile/gen-scmconfig.c +++ b/libguile/gen-scmconfig.c @@ -125,6 +125,7 @@ #include #include +#include #define pf printf @@ -279,21 +280,6 @@ main (int argc, char *argv[]) pf ("#define SCM_SIZEOF_LONG_LONG %d\n", SIZEOF_LONG_LONG); pf ("#define SCM_SIZEOF_UNSIGNED_LONG_LONG %d\n", SIZEOF_UNSIGNED_LONG_LONG); - pf("\n"); - pf("/* handling for the deprecated long_long and ulong_long types */\n"); - pf("/* If anything suitable is available, it'll be defined here. */\n"); - pf("#if (SCM_ENABLE_DEPRECATED == 1)\n"); - if (SIZEOF_LONG_LONG != 0) - pf ("typedef long long long_long;\n"); - else if (SIZEOF___INT64 != 0) - pf ("typedef __int64 long_long;\n"); - - if (SIZEOF_UNSIGNED_LONG_LONG != 0) - pf ("typedef unsigned long long ulong_long;\n"); - else if (SIZEOF_UNSIGNED___INT64 != 0) - pf ("typedef unsigned __int64 ulong_long;\n"); - pf("#endif /* SCM_ENABLE_DEPRECATED == 1 */\n"); - pf ("\n"); pf ("/* These are always defined. */\n"); pf ("typedef %s scm_t_int8;\n", SCM_I_GSC_T_INT8); @@ -400,6 +386,24 @@ main (int argc, char *argv[]) pf ("#define SCM_HAVE_READDIR64_R 0 /* 0 or 1 */\n"); #endif + /* Arrange so that we have a file offset type that reflects the one + used when compiling Guile, regardless of what the application's + `_FILE_OFFSET_BITS' says. See + http://lists.gnu.org/archive/html/bug-guile/2009-06/msg00018.html + for the original bug report. + + Note that we can't define `scm_t_off' in terms of `off_t' or + `off64_t' because they may or may not be available depending on + how the application that uses Guile is compiled. */ + +#if defined GUILE_USE_64_CALLS && defined HAVE_STAT64 + pf ("typedef scm_t_int64 scm_t_off;\n"); +#elif SIZEOF_OFF_T == SIZEOF_INT + pf ("typedef int scm_t_off;\n"); +#else + pf ("typedef long int scm_t_off;\n"); +#endif + #if USE_DLL_IMPORT pf ("\n"); pf ("/* Define some additional CPP macros on Win32 platforms. */\n"); @@ -421,6 +425,14 @@ main (int argc, char *argv[]) pf ("#define SCM_HAVE_ARRAYS 1 /* always true now */\n"); + pf ("\n"); + pf ("/* Constants from uniconv.h. */\n"); + pf ("#define SCM_ICONVEH_ERROR %d\n", (int) iconveh_error); + pf ("#define SCM_ICONVEH_QUESTION_MARK %d\n", + (int) iconveh_question_mark); + pf ("#define SCM_ICONVEH_ESCAPE_SEQUENCE %d\n", + (int) iconveh_escape_sequence); + printf ("#endif\n"); return 0; diff --git a/libguile/gettext.c b/libguile/gettext.c index e74f9f351..2ae3ae5e4 100644 --- a/libguile/gettext.c +++ b/libguile/gettext.c @@ -1,18 +1,19 @@ /* Copyright (C) 2004, 2006 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/gettext.h b/libguile/gettext.h index 8a13307d5..d4576bd6a 100644 --- a/libguile/gettext.h +++ b/libguile/gettext.h @@ -6,18 +6,19 @@ /* Copyright (C) 2004, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ #include "libguile/__scm.h" diff --git a/libguile/goops.c b/libguile/goops.c index 1d9272df6..25b957132 100644 --- a/libguile/goops.c +++ b/libguile/goops.c @@ -2,18 +2,19 @@ * Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ @@ -1253,10 +1254,7 @@ SCM_DEFINE (scm_sys_fast_slot_set_x, "%fast-slot-set!", 3, 0, 0, #undef FUNC_NAME -SCM_SYNTAX (s_atslot_ref, "@slot-ref", scm_i_makbimacro, scm_m_atslot_ref); -SCM_SYNTAX (s_atslot_set_x, "@slot-set!", scm_i_makbimacro, scm_m_atslot_set_x); - - + /** Utilities **/ /* In the future, this function will return the effective slot @@ -1859,7 +1857,7 @@ SCM_DEFINE (scm_enable_primitive_generic_x, "enable-primitive-generic!", 0, 0, 1 *SCM_SUBR_GENERIC (subr) = scm_make (scm_list_3 (scm_class_generic, k_name, - SCM_SNAME (subr))); + SCM_SUBR_NAME (subr))); subrs = SCM_CDR (subrs); } return SCM_UNSPECIFIED; @@ -1907,7 +1905,7 @@ scm_c_extend_primitive_generic (SCM extended, SCM extension) gf = *SCM_SUBR_GENERIC (extended); gext = scm_call_2 (SCM_VARIABLE_REF (scm_var_make_extended_generic), gf, - SCM_SNAME (extension)); + SCM_SUBR_NAME (extension)); SCM_SET_SUBR_GENERIC (extension, gext); } else diff --git a/libguile/goops.h b/libguile/goops.h index d43d73642..8d138237a 100644 --- a/libguile/goops.h +++ b/libguile/goops.h @@ -6,18 +6,19 @@ /* Copyright (C) 1998,1999,2000,2001,2002,2003, 2006, 2008, 2009 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/gsubr.c b/libguile/gsubr.c index 2b9a29dd1..3b7315565 100644 --- a/libguile/gsubr.c +++ b/libguile/gsubr.c @@ -1,18 +1,19 @@ /* Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2006, 2008, 2009 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ @@ -20,6 +21,8 @@ # include #endif +#include + #include #include @@ -91,7 +94,7 @@ create_gsubr (int define, const char *name, } if (define) - scm_define (SCM_SNAME (subr), subr); + scm_define (SCM_SUBR_NAME (subr), subr); return subr; } @@ -146,7 +149,7 @@ create_gsubr_with_generic (int define, subr = scm_c_make_subr_with_generic (name, scm_tc7_lsubr_2, fcn, gf); create_subr: if (define) - scm_define (SCM_SNAME (subr), subr); + scm_define (SCM_SUBR_NAME (subr), subr); return subr; default: ; @@ -193,7 +196,7 @@ gsubr_apply_raw (SCM proc, unsigned int argc, const SCM *argv) if (SCM_UNLIKELY (argc != argc_max)) /* We expect the exact argument count. */ - scm_wrong_num_args (SCM_SNAME (proc)); + scm_wrong_num_args (SCM_SUBR_NAME (proc)); fcn = SCM_SUBRF (proc); @@ -226,7 +229,7 @@ gsubr_apply_raw (SCM proc, unsigned int argc, const SCM *argv) return (*fcn) (argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9]); default: - scm_misc_error ((char *) SCM_SNAME (proc), + scm_misc_error ((char *) SCM_SUBR_NAME (proc), "gsubr invocation with more than 10 arguments not implemented", SCM_EOL); } @@ -255,7 +258,7 @@ scm_i_gsubr_apply (SCM proc, SCM arg, ...) argv[argc] = arg; if (SCM_UNLIKELY (argc < SCM_GSUBR_REQ (type))) - scm_wrong_num_args (SCM_SNAME (proc)); + scm_wrong_num_args (SCM_SUBR_NAME (proc)); /* Fill in optional arguments that were not passed. */ while (argc < argc_max) @@ -293,7 +296,7 @@ scm_i_gsubr_apply_list (SCM self, SCM args) for (i = 0; i < SCM_GSUBR_REQ (typ); i++) { if (scm_is_null (args)) - scm_wrong_num_args (SCM_SNAME (self)); + scm_wrong_num_args (SCM_SUBR_NAME (self)); v[i] = SCM_CAR(args); args = SCM_CDR(args); } @@ -308,7 +311,7 @@ scm_i_gsubr_apply_list (SCM self, SCM args) if (SCM_GSUBR_REST(typ)) v[i] = args; else if (!scm_is_null (args)) - scm_wrong_num_args (SCM_SNAME (self)); + scm_wrong_num_args (SCM_SUBR_NAME (self)); return gsubr_apply_raw (self, n, v); } diff --git a/libguile/gsubr.h b/libguile/gsubr.h index 65680a02c..298181b15 100644 --- a/libguile/gsubr.h +++ b/libguile/gsubr.h @@ -6,18 +6,19 @@ /* Copyright (C) 1995,1996,1998,2000,2001, 2006, 2008, 2009 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/guardians.c b/libguile/guardians.c index 73730fc45..580e212d0 100644 --- a/libguile/guardians.c +++ b/libguile/guardians.c @@ -1,18 +1,19 @@ /* Copyright (C) 1998,1999,2000,2001, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/guardians.h b/libguile/guardians.h index 295092edf..a23026d6c 100644 --- a/libguile/guardians.h +++ b/libguile/guardians.h @@ -6,18 +6,19 @@ /* Copyright (C) 1998,2000,2001, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/guile-doc-snarf.in b/libguile/guile-doc-snarf.in index 49be29185..a787d5a46 100755 --- a/libguile/guile-doc-snarf.in +++ b/libguile/guile-doc-snarf.in @@ -4,19 +4,19 @@ # Copyright (C) 1999, 2000, 2001, 2006 Free Software Foundation, Inc. # # 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 2, 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 software; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -# Boston, MA 02110-1301 USA +# it under the terms of the GNU Lesser General Public License as +# published by the Free Software Foundation; either version 3, 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this software; see the file COPYING.LESSER. If +# not, write to the Free Software Foundation, Inc., 51 Franklin +# Street, Fifth Floor, Boston, MA 02110-1301 USA fullfilename=$1 diff --git a/libguile/guile-func-name-check.in b/libguile/guile-func-name-check.in index 7f0114e0b..8b4924e91 100644 --- a/libguile/guile-func-name-check.in +++ b/libguile/guile-func-name-check.in @@ -3,19 +3,19 @@ # Copyright (C) 2000, 2001, 2006 Free Software Foundation, Inc. # # 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 2, or (at your option) -# any later version. +# it under the terms of the GNU Lesser General Public License as +# published by the Free Software Foundation; either version 3, 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. +# 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 +# Lesser General Public License for more details. # -# You should have received a copy of the GNU General Public License -# along with this software; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -# Boston, MA 02110-1301 USA +# You should have received a copy of the GNU Lesser General Public +# License along with this software; see the file COPYING.LESSER. If +# not, write to the Free Software Foundation, Inc., 51 Franklin +# Street, Fifth Floor, Boston, MA 02110-1301 USA # # Written by Greg J. Badros, # 11-Jan-2000 diff --git a/libguile/guile-snarf-docs.in b/libguile/guile-snarf-docs.in index 9cba3dc56..1e57f2624 100755 --- a/libguile/guile-snarf-docs.in +++ b/libguile/guile-snarf-docs.in @@ -4,19 +4,19 @@ # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2006 Free Software Foundation, Inc. # # 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 2, or (at your option) -# any later version. +# it under the terms of the GNU Lesser General Public License as +# published by the Free Software Foundation; either version 3, 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. +# 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 +# Lesser General Public License for more details. # -# You should have received a copy of the GNU General Public License -# along with this software; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -# Boston, MA 02110-1301 USA +# You should have received a copy of the GNU Lesser General Public +# License along with this software; see the file COPYING.LESSER. If +# not, write to the Free Software Foundation, Inc., 51 Franklin +# Street, Fifth Floor, Boston, MA 02110-1301 USA bindir=`dirname $0` diff --git a/libguile/guile-snarf.awk.in b/libguile/guile-snarf.awk.in index be3b1236d..8a720a002 100644 --- a/libguile/guile-snarf.awk.in +++ b/libguile/guile-snarf.awk.in @@ -1,19 +1,19 @@ # Copyright (C) 1999, 2000, 2001, 2006 Free Software Foundation, Inc. # # 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 2, or (at your option) -# any later version. +# it under the terms of the GNU Lesser General Public License as +# published by the Free Software Foundation; either version 3, 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. +# 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 +# Lesser General Public License for more details. # -# You should have received a copy of the GNU General Public License -# along with this software; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -# Boston, MA 02110-1301 USA +# You should have received a copy of the GNU Lesser General Public +# License along with this software; see the file COPYING.LESSER. If +# not, write to the Free Software Foundation, Inc., 51 Franklin +# Street, Fifth Floor, Boston, MA 02110-1301 USA # # Written by Greg J. Badros, # 12-Dec-1999 diff --git a/libguile/guile-snarf.in b/libguile/guile-snarf.in index 617bad822..6a72dd5d5 100644 --- a/libguile/guile-snarf.in +++ b/libguile/guile-snarf.in @@ -4,19 +4,19 @@ # Copyright (C) 1996, 97, 98, 99, 2000, 2001, 2002, 2004, 2006, 2008 Free Software Foundation, Inc. # # 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 2, 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 software; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -# Boston, MA 02110-1301 USA +# it under the terms of the GNU Lesser General Public License as +# published by the Free Software Foundation; either version 3, 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this software; see the file COPYING.LESSER. If +# not, write to the Free Software Foundation, Inc., 51 Franklin +# Street, Fifth Floor, Boston, MA 02110-1301 USA # Commentary: diff --git a/libguile/guile.c b/libguile/guile.c index c8341c24f..6da547b75 100644 --- a/libguile/guile.c +++ b/libguile/guile.c @@ -1,18 +1,19 @@ /* Copyright (C) 1996,1997,2000,2001, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ /* This is the 'main' function for the `guile' executable. It is not diff --git a/libguile/hash.c b/libguile/hash.c index 7a49de6b4..d2fe17706 100644 --- a/libguile/hash.c +++ b/libguile/hash.c @@ -1,18 +1,19 @@ /* Copyright (C) 1995,1996,1997, 2000, 2001, 2003, 2004, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/hash.h b/libguile/hash.h index bbf9b2562..789595b42 100644 --- a/libguile/hash.h +++ b/libguile/hash.h @@ -6,18 +6,19 @@ /* Copyright (C) 1995,1996,2000, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/hashtab.c b/libguile/hashtab.c index 50553d295..5c03d281f 100644 --- a/libguile/hashtab.c +++ b/libguile/hashtab.c @@ -1,18 +1,19 @@ /* Copyright (C) 1995,1996,1998,1999,2000,2001, 2003, 2004, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/hashtab.h b/libguile/hashtab.h index 005fd57aa..8f8ebf9ce 100644 --- a/libguile/hashtab.h +++ b/libguile/hashtab.h @@ -6,18 +6,19 @@ /* Copyright (C) 1995,1996,1999,2000,2001, 2003, 2004, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/hooks.c b/libguile/hooks.c index d175be127..c6541fadd 100644 --- a/libguile/hooks.c +++ b/libguile/hooks.c @@ -1,18 +1,19 @@ /* Copyright (C) 1995,1996,1998,1999,2000,2001, 2003, 2006, 2008, 2009 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/hooks.h b/libguile/hooks.h index 49ea55350..15b57fabb 100644 --- a/libguile/hooks.h +++ b/libguile/hooks.h @@ -6,18 +6,19 @@ /* Copyright (C) 1995,1996,1999,2000,2001, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/i18n.c b/libguile/i18n.c index a5e451ceb..fd15227b5 100644 --- a/libguile/i18n.c +++ b/libguile/i18n.c @@ -1,18 +1,19 @@ /* Copyright (C) 2006, 2007, 2008, 2009 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ #ifdef HAVE_CONFIG_H diff --git a/libguile/i18n.h b/libguile/i18n.h index 57f1654a3..df2970b4e 100644 --- a/libguile/i18n.h +++ b/libguile/i18n.h @@ -6,18 +6,19 @@ /* Copyright (C) 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ #include "libguile/__scm.h" diff --git a/libguile/ieee-754.h b/libguile/ieee-754.h new file mode 100644 index 000000000..e345efaae --- /dev/null +++ b/libguile/ieee-754.h @@ -0,0 +1,90 @@ +/* Copyright (C) 1992, 1995, 1996, 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef SCM_IEEE_754_H +#define SCM_IEEE_754_H 1 + +/* Based on glibc's and modified by Ludovic Courtès to include + all possible IEEE-754 double-precision representations. */ + + +/* IEEE 754 simple-precision format (32-bit). */ + +union scm_ieee754_float + { + float f; + + struct + { + unsigned int negative:1; + unsigned int exponent:8; + unsigned int mantissa:23; + } big_endian; + + struct + { + unsigned int mantissa:23; + unsigned int exponent:8; + unsigned int negative:1; + } little_endian; + }; + + + +/* IEEE 754 double-precision format (64-bit). */ + +union scm_ieee754_double + { + double d; + + struct + { + /* Big endian. */ + + unsigned int negative:1; + unsigned int exponent:11; + /* Together these comprise the mantissa. */ + unsigned int mantissa0:20; + unsigned int mantissa1:32; + } big_endian; + + struct + { + /* Both byte order and word order are little endian. */ + + /* Together these comprise the mantissa. */ + unsigned int mantissa1:32; + unsigned int mantissa0:20; + unsigned int exponent:11; + unsigned int negative:1; + } little_little_endian; + + struct + { + /* Byte order is little endian but word order is big endian. Not + sure this is very wide spread. */ + unsigned int mantissa0:20; + unsigned int exponent:11; + unsigned int negative:1; + unsigned int mantissa1:32; + } little_big_endian; + + }; + + +#endif /* SCM_IEEE_754_H */ diff --git a/libguile/init.c b/libguile/init.c index 3e65f02be..dbb132446 100644 --- a/libguile/init.c +++ b/libguile/init.c @@ -1,18 +1,19 @@ /* Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2002, 2003, 2004, 2006, 2009 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ @@ -37,6 +38,7 @@ #include "libguile/async.h" #include "libguile/backtrace.h" #include "libguile/boolean.h" +#include "libguile/bytevectors.h" #include "libguile/chars.h" #include "libguile/continuations.h" #include "libguile/debug.h" @@ -282,7 +284,7 @@ scm_load_startup_files () /* Load Ice-9. */ if (!scm_ice_9_already_loaded) { - scm_primitive_load_path (scm_from_locale_string ("ice-9/boot-9")); + scm_c_primitive_load_path ("ice-9/boot-9"); /* Load the init.scm file. */ if (scm_is_true (init_path)) @@ -574,6 +576,7 @@ scm_i_init_guile (SCM_STACKITEM *base) scm_init_rw (); scm_init_extensions (); + scm_bootstrap_bytevectors (); scm_bootstrap_vm (); atexit (cleanup_for_exit); diff --git a/libguile/init.h b/libguile/init.h index 3ae27d8cc..7cfae76d5 100644 --- a/libguile/init.h +++ b/libguile/init.h @@ -6,18 +6,19 @@ /* Copyright (C) 1995,1996,1997,2000, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/inline.c b/libguile/inline.c index a0c25003f..79728ff13 100644 --- a/libguile/inline.c +++ b/libguile/inline.c @@ -1,18 +1,19 @@ /* Copyright (C) 2001, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ #ifdef HAVE_CONFIG_H diff --git a/libguile/inline.h b/libguile/inline.h index ff8d2d4d1..09ee1429f 100644 --- a/libguile/inline.h +++ b/libguile/inline.h @@ -6,18 +6,19 @@ /* Copyright (C) 2001, 2002, 2003, 2004, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ /* This file is for inline functions. On platforms that don't support diff --git a/libguile/instructions.c b/libguile/instructions.c index b33c8d203..04180e5e3 100644 --- a/libguile/instructions.c +++ b/libguile/instructions.c @@ -1,49 +1,28 @@ -/* Copyright (C) 2001 Free Software Foundation, Inc. - * - * 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 2, or (at your option) - * any later version. +/* Copyright (C) 2001, 2009 Free Software Foundation, Inc. * - * 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 software; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307 USA + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * As a special exception, the Free Software Foundation gives permission - * for additional uses of the text contained in its release of GUILE. + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * The exception is that, if you link the GUILE library with other files - * to produce an executable, this does not by itself cause the - * resulting executable to be covered by the GNU General Public License. - * Your use of that executable is in no way restricted on account of - * linking the GUILE library code into it. - * - * This exception does not however invalidate any other reasons why - * the executable file might be covered by the GNU General Public License. - * - * This exception applies only to the code released by the - * Free Software Foundation under the name GUILE. If you copy - * code from other Free Software Foundation releases into a copy of - * GUILE, as the General Public License permits, the exception does - * not apply to the code that you add in this way. To avoid misleading - * anyone as to the status of such modified files, you must delete - * this exception notice from them. - * - * If you write modifications of your own for GUILE, it is your choice - * whether to permit this exception to apply to your modifications. - * If you do not wish that, delete this exception notice. */ + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ #if HAVE_CONFIG_H # include #endif #include + +#include "_scm.h" #include "vm-bootstrap.h" #include "instructions.h" @@ -74,7 +53,7 @@ fetch_instruction_table () if (SCM_UNLIKELY (!table)) { - size_t bytes = scm_op_last * sizeof(struct scm_instruction); + size_t bytes = SCM_VM_NUM_INSTRUCTIONS * sizeof(struct scm_instruction); int i; table = malloc (bytes); memset (table, 0, bytes); @@ -84,11 +63,12 @@ fetch_instruction_table () #include #include #undef VM_INSTRUCTION_TO_TABLE - for (i = 0; i < scm_op_last; i++) + for (i = 0; i < SCM_VM_NUM_INSTRUCTIONS; i++) { table[i].opcode = i; if (table[i].name) - table[i].symname = scm_from_locale_symbol (table[i].name); + table[i].symname = + scm_permanent_object (scm_from_locale_symbol (table[i].name)); else table[i].symname = SCM_BOOL_F; } @@ -106,12 +86,12 @@ scm_lookup_instruction_by_name (SCM name) if (SCM_UNLIKELY (SCM_FALSEP (instructions_by_name))) { int i; - instructions_by_name = scm_make_hash_table (SCM_I_MAKINUM (scm_op_last)); - for (i = 0; i < scm_op_last; i++) + instructions_by_name = scm_permanent_object + (scm_make_hash_table (SCM_I_MAKINUM (SCM_VM_NUM_INSTRUCTIONS))); + for (i = 0; i < SCM_VM_NUM_INSTRUCTIONS; i++) if (scm_is_true (table[i].symname)) scm_hashq_set_x (instructions_by_name, table[i].symname, SCM_I_MAKINUM (i)); - instructions_by_name = scm_permanent_object (instructions_by_name); } op = scm_hashq_ref (instructions_by_name, name, SCM_UNDEFINED); @@ -130,10 +110,11 @@ SCM_DEFINE (scm_instruction_list, "instruction-list", 0, 0, 0, #define FUNC_NAME s_scm_instruction_list { SCM list = SCM_EOL; - struct scm_instruction *ip; - for (ip = fetch_instruction_table (); ip->opcode != scm_op_last; ip++) - if (ip->name) - list = scm_cons (ip->symname, list); + int i; + struct scm_instruction *ip = fetch_instruction_table (); + for (i = 0; i < SCM_VM_NUM_INSTRUCTIONS; i++) + if (ip[i].name) + list = scm_cons (ip[i].symname, list); return scm_reverse_x (list, SCM_EOL); } #undef FUNC_NAME @@ -202,7 +183,7 @@ SCM_DEFINE (scm_opcode_to_instruction, "opcode->instruction", 1, 0, 0, SCM_MAKE_VALIDATE (1, op, I_INUMP); opcode = SCM_I_INUM (op); - if (opcode < scm_op_last) + if (opcode >= 0 && opcode < SCM_VM_NUM_INSTRUCTIONS) ret = fetch_instruction_table ()[opcode].symname; if (scm_is_false (ret)) @@ -215,6 +196,9 @@ SCM_DEFINE (scm_opcode_to_instruction, "opcode->instruction", 1, 0, 0, void scm_bootstrap_instructions (void) { + scm_c_register_extension ("libguile", "scm_init_instructions", + (scm_t_extension_init_func)scm_init_instructions, + NULL); } void diff --git a/libguile/instructions.h b/libguile/instructions.h index 4968671b5..a2263228f 100644 --- a/libguile/instructions.h +++ b/libguile/instructions.h @@ -1,50 +1,27 @@ -/* Copyright (C) 2001 Free Software Foundation, Inc. - * - * 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 2, or (at your option) - * any later version. +/* Copyright (C) 2001, 2009 Free Software Foundation, Inc. * - * 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 software; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307 USA + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * As a special exception, the Free Software Foundation gives permission - * for additional uses of the text contained in its release of GUILE. + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * The exception is that, if you link the GUILE library with other files - * to produce an executable, this does not by itself cause the - * resulting executable to be covered by the GNU General Public License. - * Your use of that executable is in no way restricted on account of - * linking the GUILE library code into it. - * - * This exception does not however invalidate any other reasons why - * the executable file might be covered by the GNU General Public License. - * - * This exception applies only to the code released by the - * Free Software Foundation under the name GUILE. If you copy - * code from other Free Software Foundation releases into a copy of - * GUILE, as the General Public License permits, the exception does - * not apply to the code that you add in this way. To avoid misleading - * anyone as to the status of such modified files, you must delete - * this exception notice from them. - * - * If you write modifications of your own for GUILE, it is your choice - * whether to permit this exception to apply to your modifications. - * If you do not wish that, delete this exception notice. */ + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ #ifndef _SCM_INSTRUCTIONS_H_ #define _SCM_INSTRUCTIONS_H_ #include -#define SCM_VM_NUM_INSTRUCTIONS (1<<7) +#define SCM_VM_NUM_INSTRUCTIONS (1<<8) #define SCM_VM_INSTRUCTION_MASK (SCM_VM_NUM_INSTRUCTIONS-1) enum scm_opcode { @@ -54,19 +31,18 @@ enum scm_opcode { #include #include #undef VM_INSTRUCTION_TO_OPCODE - scm_op_last = SCM_VM_NUM_INSTRUCTIONS }; -extern SCM scm_instruction_list (void); -extern SCM scm_instruction_p (SCM obj); -extern SCM scm_instruction_length (SCM inst); -extern SCM scm_instruction_pops (SCM inst); -extern SCM scm_instruction_pushes (SCM inst); -extern SCM scm_instruction_to_opcode (SCM inst); -extern SCM scm_opcode_to_instruction (SCM op); +SCM_API SCM scm_instruction_list (void); +SCM_API SCM scm_instruction_p (SCM obj); +SCM_API SCM scm_instruction_length (SCM inst); +SCM_API SCM scm_instruction_pops (SCM inst); +SCM_API SCM scm_instruction_pushes (SCM inst); +SCM_API SCM scm_instruction_to_opcode (SCM inst); +SCM_API SCM scm_opcode_to_instruction (SCM op); -extern void scm_bootstrap_instructions (void); -extern void scm_init_instructions (void); +SCM_INTERNAL void scm_bootstrap_instructions (void); +SCM_INTERNAL void scm_init_instructions (void); #endif /* _SCM_INSTRUCTIONS_H_ */ diff --git a/libguile/ioext.c b/libguile/ioext.c index b542664eb..6b0c9b88c 100644 --- a/libguile/ioext.c +++ b/libguile/ioext.c @@ -1,18 +1,19 @@ /* Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2006 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/ioext.h b/libguile/ioext.h index 18289ea3c..1b7b93aaf 100644 --- a/libguile/ioext.h +++ b/libguile/ioext.h @@ -6,18 +6,19 @@ /* Copyright (C) 1995,1996,1997,1998,2000,2001, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/iselect.h b/libguile/iselect.h index 5a4b30da6..760d959d8 100644 --- a/libguile/iselect.h +++ b/libguile/iselect.h @@ -6,18 +6,19 @@ /* Copyright (C) 1997,1998,2000,2001, 2002, 2006 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/keywords.c b/libguile/keywords.c index 5afa9e9e7..c415ccbab 100644 --- a/libguile/keywords.c +++ b/libguile/keywords.c @@ -1,18 +1,19 @@ /* Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2003, 2004, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/keywords.h b/libguile/keywords.h index a80e31bff..bfffe5923 100644 --- a/libguile/keywords.h +++ b/libguile/keywords.h @@ -6,18 +6,19 @@ /* Copyright (C) 1995,1996,1999,2000,2001, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/lang.c b/libguile/lang.c index 7f3986cec..85da68034 100644 --- a/libguile/lang.c +++ b/libguile/lang.c @@ -1,18 +1,19 @@ /* Copyright (C) 1999, 2000, 2001, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/lang.h b/libguile/lang.h index 991e9ca76..47128de57 100644 --- a/libguile/lang.h +++ b/libguile/lang.h @@ -6,18 +6,19 @@ /* Copyright (C) 1998, 2004, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/libguile.map b/libguile/libguile.map new file mode 100644 index 000000000..2586e0abf --- /dev/null +++ b/libguile/libguile.map @@ -0,0 +1,44 @@ +# Linker version script for libguile. -*- ld-script -*- +# +# Copyright (C) 2009 Free Software Foundation, Inc. +# +# This file is part of GUILE. +# +# GUILE is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as +# published by the Free Software Foundation; either version 3, or +# (at your option) any later version. +# +# GUILE is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with GUILE; see the file COPYING.LESSER. If not, +# write to the Free Software Foundation, Inc., 51 Franklin Street, +# Fifth Floor, Boston, MA 02110-1301 USA + +GUILE_2.0 +{ + global: + # Note: This includes `scm_i_' symbols declared as `SCM_API' (e.g., + # symbols from `deprecated.c' or symbols used by public inline + # functions or macros). + scm_*; + + # GDB interface. + gdb_options; + gdb_language; + gdb_result; + gdb_output; + gdb_output_length; + gdb_maybe_valid_type_p; + gdb_read; + gdb_eval; + gdb_print; + gdb_binding; + + local: + *; +}; diff --git a/libguile/list.c b/libguile/list.c index 07b96f5a7..70f527755 100644 --- a/libguile/list.c +++ b/libguile/list.c @@ -2,18 +2,19 @@ * Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/list.h b/libguile/list.h index 733432d76..427dcb84d 100644 --- a/libguile/list.h +++ b/libguile/list.h @@ -7,18 +7,19 @@ * Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/load.c b/libguile/load.c index 1a2994f40..505678932 100644 --- a/libguile/load.c +++ b/libguile/load.c @@ -1,18 +1,19 @@ -/* Copyright (C) 1995,1996,1998,1999,2000,2001, 2004, 2006, 2008 Free Software Foundation, Inc. +/* Copyright (C) 1995,1996,1998,1999,2000,2001, 2004, 2006, 2008, 2009 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ @@ -53,6 +54,10 @@ #include #endif /* HAVE_UNISTD_H */ +#ifdef HAVE_PWD_H +#include +#endif /* HAVE_PWD_H */ + #ifndef R_OK #define R_OK 4 #endif @@ -174,9 +179,15 @@ static SCM *scm_loc_load_path; /* List of extensions we try adding to the filenames. */ static SCM *scm_loc_load_extensions; -/* Like %load-extensions, but for compiled files. */ +/* Like %load-path and %load-extensions, but for compiled files. */ +static SCM *scm_loc_load_compiled_path; static SCM *scm_loc_load_compiled_extensions; +/* Whether we should try to auto-compile. */ +static SCM *scm_loc_load_should_autocompile; + +/* The fallback path for autocompilation */ +static SCM *scm_loc_compile_fallback_path; SCM_DEFINE (scm_parse_path, "parse-path", 1, 1, 0, (SCM path, SCM tail), @@ -209,6 +220,7 @@ scm_init_load_path () { char *env; SCM path = SCM_EOL; + SCM cpath = SCM_EOL; #ifdef SCM_LIBRARY_DIR env = getenv ("GUILE_SYSTEM_PATH"); @@ -222,13 +234,54 @@ scm_init_load_path () path = scm_list_3 (scm_from_locale_string (SCM_SITE_DIR), scm_from_locale_string (SCM_LIBRARY_DIR), scm_from_locale_string (SCM_PKGDATA_DIR)); + + env = getenv ("GUILE_SYSTEM_COMPILED_PATH"); + if (env && strcmp (env, "") == 0) + /* like above */ + ; + else if (env) + cpath = scm_parse_path (scm_from_locale_string (env), cpath); + else + cpath = scm_cons (scm_from_locale_string (SCM_CCACHE_DIR), cpath); + #endif /* SCM_LIBRARY_DIR */ + { + char cachedir[1024]; + char *e; +#ifdef HAVE_GETPWENT + struct passwd *pwd; +#endif + +#define FALLBACK_DIR \ + "guile/ccache/" SCM_EFFECTIVE_VERSION "-" SCM_OBJCODE_MACHINE_VERSION_STRING + + if ((e = getenv ("XDG_CACHE_HOME"))) + snprintf (cachedir, sizeof(cachedir), "%s" FALLBACK_DIR, e); + else if ((e = getenv ("HOME"))) + snprintf (cachedir, sizeof(cachedir), "%s/.cache/" FALLBACK_DIR, e); +#ifdef HAVE_GETPWENT + else if ((pwd = getpwuid (getuid ())) && pwd->pw_dir) + snprintf (cachedir, sizeof(cachedir), "%s/.cache/" FALLBACK_DIR, + pwd->pw_dir); +#endif /* HAVE_GETPWENT */ + else + cachedir[0] = 0; + + if (cachedir[0]) + *scm_loc_compile_fallback_path = scm_from_locale_string (cachedir); + } + env = getenv ("GUILE_LOAD_PATH"); if (env) path = scm_parse_path (scm_from_locale_string (env), path); + env = getenv ("GUILE_LOAD_COMPILED_PATH"); + if (env) + cpath = scm_parse_path (scm_from_locale_string (env), cpath); + *scm_loc_load_path = path; + *scm_loc_load_compiled_path = cpath; } SCM scm_listofnullstr; @@ -508,58 +561,191 @@ SCM_DEFINE (scm_sys_search_load_path, "%search-load-path", 1, 0, 0, #undef FUNC_NAME -SCM_DEFINE (scm_primitive_load_path, "primitive-load-path", 1, 0, 0, - (SCM filename), +static int +compiled_is_fresh (SCM full_filename, SCM compiled_filename) +{ + char *source, *compiled; + struct stat stat_source, stat_compiled; + int res; + + source = scm_to_locale_string (full_filename); + compiled = scm_to_locale_string (compiled_filename); + + if (stat (source, &stat_source) == 0 + && stat (compiled, &stat_compiled) == 0 + && stat_source.st_mtime == stat_compiled.st_mtime) + { + res = 1; + } + else + { + scm_puts (";;; note: source file ", scm_current_error_port ()); + scm_puts (source, scm_current_error_port ()); + scm_puts ("\n;;; newer than compiled ", scm_current_error_port ()); + scm_puts (compiled, scm_current_error_port ()); + scm_puts ("\n", scm_current_error_port ()); + res = 0; + } + + free (source); + free (compiled); + return res; +} + +static SCM +do_try_autocompile (void *data) +{ + SCM source = PTR2SCM (data); + SCM comp_mod, compile_file; + + scm_puts (";;; compiling ", scm_current_error_port ()); + scm_display (source, scm_current_error_port ()); + scm_newline (scm_current_error_port ()); + + comp_mod = scm_c_resolve_module ("system base compile"); + compile_file = scm_module_variable + (comp_mod, scm_from_locale_symbol ("compile-file")); + + if (scm_is_true (compile_file)) + { + SCM res = scm_call_1 (scm_variable_ref (compile_file), source); + scm_puts (";;; compiled ", scm_current_error_port ()); + scm_display (res, scm_current_error_port ()); + scm_newline (scm_current_error_port ()); + return res; + } + else + { + scm_puts (";;; it seems ", scm_current_error_port ()); + scm_display (source, scm_current_error_port ()); + scm_puts ("\n;;; is part of the compiler; skipping autocompilation\n", + scm_current_error_port ()); + return SCM_BOOL_F; + } +} + +static SCM +autocompile_catch_handler (void *data, SCM tag, SCM throw_args) +{ + SCM source = PTR2SCM (data); + scm_puts (";;; WARNING: compilation of ", scm_current_error_port ()); + scm_display (source, scm_current_error_port ()); + scm_puts (" failed:\n", scm_current_error_port ()); + scm_puts (";;; key ", scm_current_error_port ()); + scm_write (tag, scm_current_error_port ()); + scm_puts (", throw args ", scm_current_error_port ()); + scm_write (throw_args, scm_current_error_port ()); + scm_newline (scm_current_error_port ()); + return SCM_BOOL_F; +} + +static SCM +scm_try_autocompile (SCM source) +{ + static int message_shown = 0; + + if (scm_is_false (*scm_loc_load_should_autocompile)) + return SCM_BOOL_F; + + if (!message_shown) + { + scm_puts (";;; note: autocompilation is enabled, set GUILE_AUTO_COMPILE=0\n" + ";;; or pass the --no-autocompile argument to disable.\n", + scm_current_error_port ()); + message_shown = 1; + } + + return scm_c_catch (SCM_BOOL_T, + do_try_autocompile, + SCM2PTR (source), + autocompile_catch_handler, + SCM2PTR (source), + NULL, NULL); +} + +SCM_DEFINE (scm_primitive_load_path, "primitive-load-path", 1, 1, 0, + (SCM filename, SCM exception_on_not_found), "Search @var{%load-path} for the file named @var{filename} and\n" "load it into the top-level environment. If @var{filename} is a\n" "relative pathname and is not found in the list of search paths,\n" - "an error is signalled.") + "an error is signalled, unless the optional argument\n" + "@var{exception_on_not_found} is @code{#f}, in which case\n" + "@code{#f} is returned instead.") #define FUNC_NAME s_scm_primitive_load_path { SCM full_filename, compiled_filename; + int compiled_is_fallback = 0; + + if (SCM_UNBNDP (exception_on_not_found)) + exception_on_not_found = SCM_BOOL_T; full_filename = scm_sys_search_load_path (filename); - compiled_filename = scm_search_path (*scm_loc_load_path, + compiled_filename = scm_search_path (*scm_loc_load_compiled_path, filename, *scm_loc_load_compiled_extensions, SCM_BOOL_T); - + + if (scm_is_false (compiled_filename) + && scm_is_true (full_filename) + && scm_is_true (*scm_loc_compile_fallback_path) + && scm_is_pair (*scm_loc_load_compiled_extensions) + && scm_is_string (scm_car (*scm_loc_load_compiled_extensions))) + { + SCM fallback = scm_string_append + (scm_list_3 (*scm_loc_compile_fallback_path, + full_filename, + scm_car (*scm_loc_load_compiled_extensions))); + if (scm_is_true (scm_stat (fallback, SCM_BOOL_F))) + { + compiled_filename = fallback; + compiled_is_fallback = 1; + } + } + if (scm_is_false (full_filename) && scm_is_false (compiled_filename)) - SCM_MISC_ERROR ("Unable to find file ~S in load path", - scm_list_1 (filename)); + { + if (scm_is_true (exception_on_not_found)) + SCM_MISC_ERROR ("Unable to find file ~S in load path", + scm_list_1 (filename)); + else + return SCM_BOOL_F; + } - if (scm_is_false (compiled_filename)) - return scm_primitive_load (full_filename); - - if (scm_is_false (full_filename)) + if (scm_is_false (full_filename) + || (scm_is_true (compiled_filename) + && compiled_is_fresh (full_filename, compiled_filename))) return scm_load_compiled_with_vm (compiled_filename); - { - char *source, *compiled; - struct stat stat_source, stat_compiled; + /* Perhaps there was the installed .go that was stale, but our fallback is + fresh. Let's try that. Duplicating code, but perhaps that's OK. */ - source = scm_to_locale_string (full_filename); - compiled = scm_to_locale_string (compiled_filename); - - if (stat (source, &stat_source) == 0 - && stat (compiled, &stat_compiled) == 0 - && stat_source.st_mtime <= stat_compiled.st_mtime) - { - free (source); - free (compiled); - return scm_load_compiled_with_vm (compiled_filename); - } + if (!compiled_is_fallback + && scm_is_true (*scm_loc_compile_fallback_path) + && scm_is_pair (*scm_loc_load_compiled_extensions) + && scm_is_string (scm_car (*scm_loc_load_compiled_extensions))) + { + SCM fallback = scm_string_append + (scm_list_3 (*scm_loc_compile_fallback_path, + full_filename, + scm_car (*scm_loc_load_compiled_extensions))); + if (scm_is_true (scm_stat (fallback, SCM_BOOL_F)) + && compiled_is_fresh (full_filename, fallback)) + { + scm_puts (";;; found fresh local cache at ", scm_current_error_port ()); + scm_display (fallback, scm_current_error_port ()); + scm_newline (scm_current_error_port ()); + return scm_load_compiled_with_vm (compiled_filename); + } + } + + /* Otherwise, we bottom out here. */ + { + SCM freshly_compiled = scm_try_autocompile (full_filename); + + if (scm_is_true (freshly_compiled)) + return scm_load_compiled_with_vm (freshly_compiled); else - { - scm_puts (";;; note: source file ", scm_current_error_port ()); - scm_puts (source, scm_current_error_port ()); - scm_puts (" newer than compiled ", scm_current_error_port ()); - scm_puts (compiled, scm_current_error_port ()); - scm_puts ("\n", scm_current_error_port ()); - free (source); - free (compiled); - return scm_primitive_load (full_filename); - } + return scm_primitive_load (full_filename); } } #undef FUNC_NAME @@ -567,7 +753,8 @@ SCM_DEFINE (scm_primitive_load_path, "primitive-load-path", 1, 0, 0, SCM scm_c_primitive_load_path (const char *filename) { - return scm_primitive_load_path (scm_from_locale_string (filename)); + return scm_primitive_load_path (scm_from_locale_string (filename), + SCM_BOOL_T); } @@ -600,11 +787,19 @@ scm_init_load () = SCM_VARIABLE_LOC (scm_c_define ("%load-extensions", scm_list_2 (scm_from_locale_string (".scm"), scm_nullstr))); + scm_loc_load_compiled_path + = SCM_VARIABLE_LOC (scm_c_define ("%load-compiled-path", SCM_EOL)); scm_loc_load_compiled_extensions = SCM_VARIABLE_LOC (scm_c_define ("%load-compiled-extensions", scm_list_1 (scm_from_locale_string (".go")))); scm_loc_load_hook = SCM_VARIABLE_LOC (scm_c_define ("%load-hook", SCM_BOOL_F)); + scm_loc_compile_fallback_path + = SCM_VARIABLE_LOC (scm_c_define ("%compile-fallback-path", SCM_BOOL_F)); + + scm_loc_load_should_autocompile + = SCM_VARIABLE_LOC (scm_c_define ("%load-should-autocompile", SCM_BOOL_F)); + the_reader = scm_make_fluid (); scm_fluid_set_x (the_reader, SCM_BOOL_F); scm_c_define("current-reader", the_reader); diff --git a/libguile/load.h b/libguile/load.h index 87f336e1e..d5bc1b066 100644 --- a/libguile/load.h +++ b/libguile/load.h @@ -6,18 +6,19 @@ /* Copyright (C) 1995,1996,1998,2000,2001, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ @@ -33,7 +34,7 @@ SCM_API SCM scm_sys_library_dir (void); SCM_API SCM scm_sys_site_dir (void); SCM_API SCM scm_search_path (SCM path, SCM filename, SCM exts, SCM require_exts); SCM_API SCM scm_sys_search_load_path (SCM filename); -SCM_API SCM scm_primitive_load_path (SCM filename); +SCM_API SCM scm_primitive_load_path (SCM filename, SCM exception_on_not_found); SCM_API SCM scm_c_primitive_load_path (const char *filename); SCM_INTERNAL void scm_init_load_path (void); SCM_INTERNAL void scm_init_load (void); diff --git a/libguile/locale-categories.h b/libguile/locale-categories.h index cbe9684a3..26b030dc5 100644 --- a/libguile/locale-categories.h +++ b/libguile/locale-categories.h @@ -1,18 +1,19 @@ /* Copyright (C) 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ /* A list of all available locale categories, not including `ALL'. */ diff --git a/libguile/macros.c b/libguile/macros.c index 076b72dbb..3e0942c43 100644 --- a/libguile/macros.c +++ b/libguile/macros.c @@ -1,18 +1,19 @@ -/* Copyright (C) 1995,1996,1997,1998,2000,2001,2002,2003, 2006, 2008 Free Software Foundation, Inc. +/* Copyright (C) 1995,1996,1997,1998,2000,2001,2002,2003, 2006, 2008, 2009 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ @@ -48,10 +49,13 @@ macro_print (SCM macro, SCM port, scm_print_state *pstate) || scm_is_false (scm_printer_apply (SCM_PRINT_CLOSURE, macro, port, pstate))) { + scm_puts ("#<", port); + + if (SCM_MACRO_TYPE (macro) < 4 && SCM_MACRO_IS_EXTENDED (macro)) + scm_puts ("extended-", port); + if (!SCM_CLOSUREP (code) && !SCM_PROGRAM_P (code)) - scm_puts ("#', port); } @@ -164,11 +178,45 @@ SCM_DEFINE (scm_makmacro, "procedure->macro", 1, 0, 0, #endif +SCM_DEFINE (scm_make_syncase_macro, "make-syncase-macro", 2, 0, 0, + (SCM type, SCM binding), + "Return a @dfn{macro} that requires expansion by syntax-case.\n" + "While users should not call this function, it is useful to know\n" + "that syntax-case macros are represented as Guile primitive macros.") +#define FUNC_NAME s_scm_make_syncase_macro +{ + SCM z; + SCM_VALIDATE_SYMBOL (1, type); + + SCM_NEWSMOB3 (z, scm_tc16_macro, SCM_UNPACK (binding), SCM_UNPACK (type), + SCM_UNPACK (binding)); + SCM_SET_SMOB_FLAGS (z, 4 | SCM_F_MACRO_EXTENDED); + return z; +} +#undef FUNC_NAME + +SCM_DEFINE (scm_make_extended_syncase_macro, "make-extended-syncase-macro", 3, 0, 0, + (SCM m, SCM type, SCM binding), + "Extend a core macro @var{m} with a syntax-case binding.") +#define FUNC_NAME s_scm_make_extended_syncase_macro +{ + SCM z; + SCM_VALIDATE_SMOB (1, m, macro); + SCM_VALIDATE_SYMBOL (2, type); + + SCM_NEWSMOB3 (z, scm_tc16_macro, SCM_SMOB_DATA (m), SCM_UNPACK (type), + SCM_UNPACK (binding)); + SCM_SET_SMOB_FLAGS (z, SCM_SMOB_FLAGS (m) | SCM_F_MACRO_EXTENDED); + return z; +} +#undef FUNC_NAME + + SCM_DEFINE (scm_macro_p, "macro?", 1, 0, 0, (SCM obj), - "Return @code{#t} if @var{obj} is a regular macro, a memoizing macro or a\n" - "syntax transformer.") + "Return @code{#t} if @var{obj} is a regular macro, a memoizing macro, a\n" + "syntax transformer, or a syntax-case macro.") #define FUNC_NAME s_scm_macro_p { return scm_from_bool (SCM_SMOB_PREDICATE (scm_tc16_macro, obj)); @@ -182,14 +230,15 @@ SCM_SYMBOL (scm_sym_macro, "macro"); #endif SCM_SYMBOL (scm_sym_mmacro, "macro!"); SCM_SYMBOL (scm_sym_bimacro, "builtin-macro!"); +SCM_SYMBOL (scm_sym_syncase_macro, "syncase-macro"); SCM_DEFINE (scm_macro_type, "macro-type", 1, 0, 0, (SCM m), - "Return one of the symbols @code{syntax}, @code{macro} or\n" - "@code{macro!}, depending on whether @var{m} is a syntax\n" - "transformer, a regular macro, or a memoizing macro,\n" - "respectively. If @var{m} is not a macro, @code{#f} is\n" - "returned.") + "Return one of the symbols @code{syntax}, @code{macro},\n" + "@code{macro!}, or @code{syntax-case}, depending on whether\n" + "@var{m} is a syntax transformer, a regular macro, a memoizing\n" + "macro, or a syntax-case macro, respectively. If @var{m} is\n" + "not a macro, @code{#f} is returned.") #define FUNC_NAME s_scm_macro_type { if (!SCM_SMOB_PREDICATE (scm_tc16_macro, m)) @@ -202,6 +251,7 @@ SCM_DEFINE (scm_macro_type, "macro-type", 1, 0, 0, #endif case 2: return scm_sym_mmacro; case 3: return scm_sym_bimacro; + case 4: return scm_sym_syncase_macro; default: scm_wrong_type_arg (FUNC_NAME, 1, m); } } @@ -214,7 +264,9 @@ SCM_DEFINE (scm_macro_name, "macro-name", 1, 0, 0, #define FUNC_NAME s_scm_macro_name { SCM_VALIDATE_SMOB (1, m, macro); - return scm_procedure_name (SCM_PACK (SCM_SMOB_DATA (m))); + if (scm_is_true (scm_procedure_p (SCM_SMOB_OBJECT (m)))) + return scm_procedure_name (SCM_SMOB_OBJECT (m)); + return SCM_BOOL_F; } #undef FUNC_NAME @@ -236,6 +288,34 @@ SCM_DEFINE (scm_macro_transformer, "macro-transformer", 1, 0, 0, } #undef FUNC_NAME +SCM_DEFINE (scm_syncase_macro_type, "syncase-macro-type", 1, 0, 0, + (SCM m), + "Return the type of the macro @var{m}.") +#define FUNC_NAME s_scm_syncase_macro_type +{ + SCM_VALIDATE_SMOB (1, m, macro); + + if (SCM_MACRO_IS_EXTENDED (m)) + return SCM_SMOB_OBJECT_2 (m); + else + return SCM_BOOL_F; +} +#undef FUNC_NAME + +SCM_DEFINE (scm_syncase_macro_binding, "syncase-macro-binding", 1, 0, 0, + (SCM m), + "Return the binding of the macro @var{m}.") +#define FUNC_NAME s_scm_syncase_macro_binding +{ + SCM_VALIDATE_SMOB (1, m, macro); + + if (SCM_MACRO_IS_EXTENDED (m)) + return SCM_SMOB_OBJECT_3 (m); + else + return SCM_BOOL_F; +} +#undef FUNC_NAME + SCM scm_make_synt (const char *name, SCM (*macroizer) (), SCM (*fcn)() ) { diff --git a/libguile/macros.h b/libguile/macros.h index e1de77ff9..8ff41c4a4 100644 --- a/libguile/macros.h +++ b/libguile/macros.h @@ -6,18 +6,19 @@ /* Copyright (C) 1998,2000,2001,2002,2003, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ @@ -29,9 +30,15 @@ #define SCM_ASSYNT(_cond, _msg, _subr) \ if (!(_cond)) scm_misc_error (_subr, _msg, SCM_EOL); +#define SCM_MACRO_TYPE_BITS (3) +#define SCM_MACRO_TYPE_MASK ((1< @@ -51,12 +28,14 @@ #include #include +#include "_scm.h" #include "vm-bootstrap.h" #include "programs.h" #include "objcodes.h" -/* nb, the length of the header should be a multiple of 8 bytes */ -#define OBJCODE_COOKIE "GOOF-0.5" +/* SCM_OBJCODE_COOKIE is defined in _scm.h */ +/* The length of the header must be a multiple of 8 bytes. */ +verify (((sizeof (SCM_OBJCODE_COOKIE) - 1) & 7) == 0); /* @@ -79,25 +58,39 @@ make_objcode_by_mmap (int fd) if (ret < 0) SCM_SYSERROR; - if (st.st_size <= sizeof (struct scm_objcode) + strlen (OBJCODE_COOKIE)) + if (st.st_size <= sizeof (struct scm_objcode) + strlen (SCM_OBJCODE_COOKIE)) scm_misc_error (FUNC_NAME, "object file too small (~a bytes)", - SCM_LIST1 (SCM_I_MAKINUM (st.st_size))); + scm_list_1 (SCM_I_MAKINUM (st.st_size))); addr = mmap (0, st.st_size, PROT_READ, MAP_SHARED, fd, 0); if (addr == MAP_FAILED) - SCM_SYSERROR; + { + (void) close (fd); + SCM_SYSERROR; + } - if (memcmp (addr, OBJCODE_COOKIE, strlen (OBJCODE_COOKIE))) - SCM_SYSERROR; + if (memcmp (addr, SCM_OBJCODE_COOKIE, strlen (SCM_OBJCODE_COOKIE))) + { + SCM args = scm_list_1 (scm_from_locale_stringn + (addr, strlen (SCM_OBJCODE_COOKIE))); + (void) close (fd); + (void) munmap (addr, st.st_size); + scm_misc_error (FUNC_NAME, "bad header on object file: ~s", args); + } - data = (struct scm_objcode*)(addr + strlen (OBJCODE_COOKIE)); + data = (struct scm_objcode*)(addr + strlen (SCM_OBJCODE_COOKIE)); - if (data->len + data->metalen != (st.st_size - sizeof (*data) - strlen (OBJCODE_COOKIE))) - scm_misc_error (FUNC_NAME, "bad length header (~a, ~a)", - SCM_LIST2 (scm_from_size_t (st.st_size), - scm_from_uint32 (sizeof (*data) + data->len + data->metalen))); + if (data->len + data->metalen != (st.st_size - sizeof (*data) - strlen (SCM_OBJCODE_COOKIE))) + { + (void) close (fd); + (void) munmap (addr, st.st_size); + scm_misc_error (FUNC_NAME, "bad length header (~a, ~a)", + scm_list_2 (scm_from_size_t (st.st_size), + scm_from_uint32 (sizeof (*data) + data->len + + data->metalen))); + } - SCM_NEWSMOB3 (sret, scm_tc16_objcode, addr + strlen (OBJCODE_COOKIE), + SCM_NEWSMOB3 (sret, scm_tc16_objcode, addr + strlen (SCM_OBJCODE_COOKIE), SCM_PACK (SCM_BOOL_F), fd); SCM_SET_SMOB_FLAGS (sret, SCM_F_OBJCODE_IS_MMAP); @@ -108,10 +101,10 @@ make_objcode_by_mmap (int fd) #undef FUNC_NAME SCM -scm_c_make_objcode_slice (SCM parent, scm_t_uint8 *ptr) +scm_c_make_objcode_slice (SCM parent, const scm_t_uint8 *ptr) #define FUNC_NAME "make-objcode-slice" { - struct scm_objcode *data, *parent_data; + const struct scm_objcode *data, *parent_data; SCM ret; SCM_VALIDATE_OBJCODE (1, parent); @@ -121,10 +114,16 @@ scm_c_make_objcode_slice (SCM parent, scm_t_uint8 *ptr) || ptr >= (parent_data->base + parent_data->len + parent_data->metalen - sizeof (struct scm_objcode))) scm_misc_error (FUNC_NAME, "offset out of bounds (~a vs ~a + ~a + ~a)", - SCM_LIST4 (scm_from_ulong ((unsigned long)ptr), - scm_from_ulong ((unsigned long)parent_data->base), - scm_from_uint32 (parent_data->len), - scm_from_uint32 (parent_data->metalen))); + scm_list_4 (scm_from_ulong ((unsigned long)ptr), + scm_from_ulong ((unsigned long)parent_data->base), + scm_from_uint32 (parent_data->len), + scm_from_uint32 (parent_data->metalen))); + +#ifdef __GNUC__ /* we need `__alignof__' */ + /* Make sure bytecode for the objcode-meta is suitable aligned. Failing to + do so leads to SIGBUS/SIGSEGV on some arches (e.g., SPARC). */ + assert ((((scm_t_bits) ptr) & (__alignof__ (struct scm_objcode) - 1UL)) == 0); +#endif data = (struct scm_objcode*)ptr; if (data->base + data->len + data->metalen > parent_data->base + parent_data->len + parent_data->metalen) @@ -188,8 +187,8 @@ SCM_DEFINE (scm_bytecode_to_objcode, "bytecode->objcode", 1, 0, 0, SCM_ASSERT_RANGE (0, bytecode, size >= sizeof(struct scm_objcode)); if (data->len + data->metalen != (size - sizeof (*data))) scm_misc_error (FUNC_NAME, "bad u8vector size (~a != ~a)", - SCM_LIST2 (scm_from_size_t (size), - scm_from_uint32 (sizeof (*data) + data->len + data->metalen))); + scm_list_2 (scm_from_size_t (size), + scm_from_uint32 (sizeof (*data) + data->len + data->metalen))); assert (increment == 1); SCM_SET_SMOB_FLAGS (objcode, SCM_F_OBJCODE_IS_U8VECTOR); @@ -246,7 +245,7 @@ SCM_DEFINE (scm_write_objcode, "write-objcode", 2, 0, 0, SCM_VALIDATE_OBJCODE (1, objcode); SCM_VALIDATE_OUTPUT_PORT (2, port); - scm_c_write (port, OBJCODE_COOKIE, strlen (OBJCODE_COOKIE)); + scm_c_write (port, SCM_OBJCODE_COOKIE, strlen (SCM_OBJCODE_COOKIE)); scm_c_write (port, SCM_OBJCODE_DATA (objcode), sizeof (struct scm_objcode) + SCM_OBJCODE_TOTAL_LEN (objcode)); @@ -259,6 +258,8 @@ void scm_bootstrap_objcodes (void) { scm_tc16_objcode = scm_make_smob_type ("objcode", 0); + scm_c_register_extension ("libguile", "scm_init_objcodes", + (scm_t_extension_init_func)scm_init_objcodes, NULL); } /* Before, we used __BYTE_ORDER, but that is not defined on all diff --git a/libguile/objcodes.h b/libguile/objcodes.h index 222691668..2bb4e6040 100644 --- a/libguile/objcodes.h +++ b/libguile/objcodes.h @@ -1,43 +1,20 @@ -/* Copyright (C) 2001 Free Software Foundation, Inc. +/* Copyright (C) 2001, 2009 Free Software Foundation, Inc. * - * 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 2, 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 software; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307 USA + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * As a special exception, the Free Software Foundation gives permission - * for additional uses of the text contained in its release of GUILE. + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * The exception is that, if you link the GUILE library with other files - * to produce an executable, this does not by itself cause the - * resulting executable to be covered by the GNU General Public License. - * Your use of that executable is in no way restricted on account of - * linking the GUILE library code into it. - * - * This exception does not however invalidate any other reasons why - * the executable file might be covered by the GNU General Public License. - * - * This exception applies only to the code released by the - * Free Software Foundation under the name GUILE. If you copy - * code from other Free Software Foundation releases into a copy of - * GUILE, as the General Public License permits, the exception does - * not apply to the code that you add in this way. To avoid misleading - * anyone as to the status of such modified files, you must delete - * this exception notice from them. - * - * If you write modifications of your own for GUILE, it is your choice - * whether to permit this exception to apply to your modifications. - * If you do not wish that, delete this exception notice. */ + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ #ifndef _SCM_OBJCODES_H_ #define _SCM_OBJCODES_H_ @@ -48,11 +25,11 @@ struct scm_objcode { scm_t_uint8 nargs; scm_t_uint8 nrest; - scm_t_uint8 nlocs; - scm_t_uint8 nexts; + scm_t_uint16 nlocs; scm_t_uint32 len; /* the maximum index of base[] */ scm_t_uint32 metalen; /* well, i lie. this many bytes at the end of base[] for metadata */ + scm_t_uint32 unused; /* pad so that `base' is 8-byte aligned */ scm_t_uint8 base[0]; }; @@ -60,7 +37,7 @@ struct scm_objcode { #define SCM_F_OBJCODE_IS_U8VECTOR (1<<1) #define SCM_F_OBJCODE_IS_SLICE (1<<2) -extern scm_t_bits scm_tc16_objcode; +SCM_API scm_t_bits scm_tc16_objcode; #define SCM_OBJCODE_P(x) (SCM_SMOB_PREDICATE (scm_tc16_objcode, x)) #define SCM_OBJCODE_DATA(x) ((struct scm_objcode *) SCM_SMOB_DATA (x)) @@ -72,23 +49,22 @@ extern scm_t_bits scm_tc16_objcode; #define SCM_OBJCODE_NARGS(x) (SCM_OBJCODE_DATA (x)->nargs) #define SCM_OBJCODE_NREST(x) (SCM_OBJCODE_DATA (x)->nrest) #define SCM_OBJCODE_NLOCS(x) (SCM_OBJCODE_DATA (x)->nlocs) -#define SCM_OBJCODE_NEXTS(x) (SCM_OBJCODE_DATA (x)->nexts) #define SCM_OBJCODE_BASE(x) (SCM_OBJCODE_DATA (x)->base) #define SCM_OBJCODE_IS_MMAP(x) (SCM_SMOB_FLAGS (x) & SCM_F_OBJCODE_IS_MMAP) #define SCM_OBJCODE_IS_U8VECTOR(x) (SCM_SMOB_FLAGS (x) & SCM_F_OBJCODE_IS_U8VECTOR) #define SCM_OBJCODE_IS_SLICE(x) (SCM_SMOB_FLAGS (x) & SCM_F_OBJCODE_IS_SLICE) -SCM scm_c_make_objcode_slice (SCM parent, scm_t_uint8 *ptr); -extern SCM scm_load_objcode (SCM file); -extern SCM scm_objcode_p (SCM obj); -extern SCM scm_objcode_meta (SCM objcode); -extern SCM scm_bytecode_to_objcode (SCM bytecode); -extern SCM scm_objcode_to_bytecode (SCM objcode); -extern SCM scm_write_objcode (SCM objcode, SCM port); +SCM scm_c_make_objcode_slice (SCM parent, const scm_t_uint8 *ptr); +SCM_API SCM scm_load_objcode (SCM file); +SCM_API SCM scm_objcode_p (SCM obj); +SCM_API SCM scm_objcode_meta (SCM objcode); +SCM_API SCM scm_bytecode_to_objcode (SCM bytecode); +SCM_API SCM scm_objcode_to_bytecode (SCM objcode); +SCM_API SCM scm_write_objcode (SCM objcode, SCM port); -extern void scm_bootstrap_objcodes (void); -extern void scm_init_objcodes (void); +SCM_INTERNAL void scm_bootstrap_objcodes (void); +SCM_INTERNAL void scm_init_objcodes (void); #endif /* _SCM_OBJCODES_H_ */ diff --git a/libguile/objects.c b/libguile/objects.c index 628ddaada..f686c3a00 100644 --- a/libguile/objects.c +++ b/libguile/objects.c @@ -1,18 +1,19 @@ /* Copyright (C) 1995,1996,1999,2000,2001, 2003, 2004, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/objects.h b/libguile/objects.h index 9b2a0ed5a..914a7ea74 100644 --- a/libguile/objects.h +++ b/libguile/objects.h @@ -6,18 +6,19 @@ /* Copyright (C) 1996,1999,2000,2001, 2003, 2006, 2008, 2009 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/objprop.c b/libguile/objprop.c index 8e9486f54..6dd1da631 100644 --- a/libguile/objprop.c +++ b/libguile/objprop.c @@ -1,18 +1,19 @@ /* Copyright (C) 1995,1996, 2000, 2001, 2003, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/objprop.h b/libguile/objprop.h index 7e5365a74..f9a2e945d 100644 --- a/libguile/objprop.h +++ b/libguile/objprop.h @@ -6,18 +6,19 @@ /* Copyright (C) 1995,2000,2001, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/options.c b/libguile/options.c index cc3d452e6..ee7001a8c 100644 --- a/libguile/options.c +++ b/libguile/options.c @@ -1,18 +1,19 @@ /* Copyright (C) 1995,1996,1998,2000,2001, 2006, 2008 Free Software Foundation * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/options.h b/libguile/options.h index 4facdce01..8ea960b3c 100644 --- a/libguile/options.h +++ b/libguile/options.h @@ -6,18 +6,19 @@ /* Copyright (C) 1995,1996,2000,2001, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/pairs.c b/libguile/pairs.c index cb2d64260..aaaeb110f 100644 --- a/libguile/pairs.c +++ b/libguile/pairs.c @@ -1,18 +1,19 @@ /* Copyright (C) 1995,1996,2000,2001, 2004, 2005, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/pairs.h b/libguile/pairs.h index 61af24efe..a6d44d289 100644 --- a/libguile/pairs.h +++ b/libguile/pairs.h @@ -6,18 +6,19 @@ /* Copyright (C) 1995,1996,2000,2001, 2004, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/ports.c b/libguile/ports.c index 454b51085..2d0e26b39 100644 --- a/libguile/ports.c +++ b/libguile/ports.c @@ -1,18 +1,19 @@ /* Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2003, 2004, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ @@ -221,15 +222,14 @@ scm_set_port_close (scm_t_bits tc, int (*close) (SCM)) } void -scm_set_port_seek (scm_t_bits tc, off_t (*seek) (SCM port, - off_t OFFSET, - int WHENCE)) +scm_set_port_seek (scm_t_bits tc, + scm_t_off (*seek) (SCM, scm_t_off, int)) { scm_ptobs[SCM_TC2PTOBNUM (tc)].seek = seek; } void -scm_set_port_truncate (scm_t_bits tc, void (*truncate) (SCM port, off_t length)) +scm_set_port_truncate (scm_t_bits tc, void (*truncate) (SCM, scm_t_off)) { scm_ptobs[SCM_TC2PTOBNUM (tc)].truncate = truncate; } @@ -1034,7 +1034,24 @@ scm_fill_input (SCM port) * This function differs from scm_c_write; it updates port line and * column. */ -void +static void +update_port_lf (scm_t_wchar c, SCM port) +{ + if (c == '\a') + ; /* Do nothing. */ + else if (c == '\b') + SCM_DECCOL (port); + else if (c == '\n') + SCM_INCLINE (port); + else if (c == '\r') + SCM_ZEROCOL (port); + else if (c == '\t') + SCM_TABCOL (port); + else + SCM_INCCOL (port); +} + +void scm_lfwrite (const char *ptr, size_t size, SCM port) { scm_t_port *pt = SCM_PTAB_ENTRY (port); @@ -1045,30 +1062,54 @@ scm_lfwrite (const char *ptr, size_t size, SCM port) ptob->write (port, ptr, size); - for (; size; ptr++, size--) { - if (*ptr == '\a') { - } - else if (*ptr == '\b') { - SCM_DECCOL(port); - } - else if (*ptr == '\n') { - SCM_INCLINE(port); - } - else if (*ptr == '\r') { - SCM_ZEROCOL(port); - } - else if (*ptr == '\t') { - SCM_TABCOL(port); - } - else { - SCM_INCCOL(port); - } - } + for (; size; ptr++, size--) + update_port_lf ((scm_t_wchar) (unsigned char) *ptr, port); if (pt->rw_random) pt->rw_active = SCM_PORT_WRITE; } +/* Write a scheme string STR to PORT from START inclusive to END + exclusive. */ +void +scm_lfwrite_substr (SCM str, size_t start, size_t end, SCM port) +{ + size_t i, size = scm_i_string_length (str); + scm_t_port *pt = SCM_PTAB_ENTRY (port); + scm_t_ptob_descriptor *ptob = &scm_ptobs[SCM_PTOBNUM (port)]; + scm_t_wchar p; + char *buf; + size_t len; + + if (pt->rw_active == SCM_PORT_READ) + scm_end_input (port); + + if (end == (size_t) (-1)) + end = size; + size = end - start; + + buf = scm_to_stringn (scm_c_substring (str, start, end), &len, + NULL, SCM_FAILED_CONVERSION_ESCAPE_SEQUENCE); + ptob->write (port, buf, len); + free (buf); + + for (i = 0; i < size; i++) + { + p = scm_i_string_ref (str, i + start); + update_port_lf (p, port); + } + + if (pt->rw_random) + pt->rw_active = SCM_PORT_WRITE; +} + +/* Write a scheme string STR to PORT. */ +void +scm_lfwrite_str (SCM str, SCM port) +{ + scm_lfwrite_substr (str, 0, (size_t) (-1), port); +} + /* scm_c_read * * Used by an application to read arbitrary number of bytes from an @@ -1458,23 +1499,18 @@ SCM_DEFINE (scm_seek, "seek", 3, 0, 0, if (how != SEEK_SET && how != SEEK_CUR && how != SEEK_END) SCM_OUT_OF_RANGE (3, whence); - if (SCM_OPFPORTP (fd_port)) - { - /* go direct to fport code to allow 64-bit offsets */ - return scm_i_fport_seek (fd_port, offset, how); - } - else if (SCM_OPPORTP (fd_port)) + if (SCM_OPPORTP (fd_port)) { scm_t_ptob_descriptor *ptob = scm_ptobs + SCM_PTOBNUM (fd_port); - off_t off = scm_to_off_t (offset); - off_t rv; + off_t_or_off64_t off = scm_to_off_t_or_off64_t (offset); + off_t_or_off64_t rv; if (!ptob->seek) SCM_MISC_ERROR ("port is not seekable", scm_cons (fd_port, SCM_EOL)); else rv = ptob->seek (fd_port, off, how); - return scm_from_off_t (rv); + return scm_from_off_t_or_off64_t (rv); } else /* file descriptor?. */ { @@ -1556,14 +1592,9 @@ SCM_DEFINE (scm_truncate_file, "truncate-file", 1, 1, 0, SCM_SYSCALL (rv = ftruncate_or_ftruncate64 (scm_to_int (object), c_length)); } - else if (SCM_OPOUTFPORTP (object)) - { - /* go direct to fport code to allow 64-bit offsets */ - rv = scm_i_fport_truncate (object, length); - } else if (SCM_OPOUTPORTP (object)) { - off_t c_length = scm_to_off_t (length); + off_t_or_off64_t c_length = scm_to_off_t_or_off64_t (length); scm_t_port *pt = SCM_PTAB_ENTRY (object); scm_t_ptob_descriptor *ptob = scm_ptobs + SCM_PTOBNUM (object); diff --git a/libguile/ports.h b/libguile/ports.h index 5e42a3468..bfe59ae9a 100644 --- a/libguile/ports.h +++ b/libguile/ports.h @@ -6,18 +6,19 @@ /* Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2003, 2004, 2006, 2008, 2009 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ @@ -28,8 +29,6 @@ #include "libguile/struct.h" #include "libguile/threads.h" -/* Not sure if this is a good idea. We need it for off_t. */ -#include @@ -69,7 +68,7 @@ typedef struct unsigned char *read_buf; /* buffer start. */ const unsigned char *read_pos;/* the next unread char. */ unsigned char *read_end; /* pointer to last buffered char + 1. */ - off_t read_buf_size; /* size of the buffer. */ + scm_t_off read_buf_size; /* size of the buffer. */ /* when chars are put back into the buffer, e.g., using peek-char or unread-string, the read-buffer pointers are switched to cbuf. @@ -78,7 +77,7 @@ typedef struct unsigned char *saved_read_buf; const unsigned char *saved_read_pos; unsigned char *saved_read_end; - off_t saved_read_buf_size; + scm_t_off saved_read_buf_size; /* write requests are saved into this buffer at write_pos until it reaches write_buf + write_buf_size, then the ptob flush is @@ -87,7 +86,7 @@ typedef struct unsigned char *write_buf; /* buffer start. */ unsigned char *write_pos; /* pointer to last buffered char + 1. */ unsigned char *write_end; /* pointer to end of buffer + 1. */ - off_t write_buf_size; /* size of the buffer. */ + scm_t_off write_buf_size; /* size of the buffer. */ unsigned char shortbuf; /* buffer for "unbuffered" streams. */ @@ -156,11 +155,11 @@ SCM_INTERNAL SCM scm_i_port_weak_hash; #define SCM_REVEALED(x) (SCM_PTAB_ENTRY(x)->revealed) #define SCM_SETREVEALED(x, s) (SCM_PTAB_ENTRY(x)->revealed = (s)) -#define SCM_INCLINE(port) {SCM_LINUM (port) += 1; SCM_COL (port) = 0;} -#define SCM_ZEROCOL(port) {SCM_COL (port) = 0;} -#define SCM_INCCOL(port) {SCM_COL (port) += 1;} -#define SCM_DECCOL(port) {if (SCM_COL (port) > 0) SCM_COL (port) -= 1;} -#define SCM_TABCOL(port) {SCM_COL (port) += 8 - SCM_COL (port) % 8;} +#define SCM_INCLINE(port) do {SCM_LINUM (port) += 1; SCM_COL (port) = 0;} while (0) +#define SCM_ZEROCOL(port) do {SCM_COL (port) = 0;} while (0) +#define SCM_INCCOL(port) do {SCM_COL (port) += 1;} while (0) +#define SCM_DECCOL(port) do {if (SCM_COL (port) > 0) SCM_COL (port) -= 1;} while (0) +#define SCM_TABCOL(port) do {SCM_COL (port) += 8 - SCM_COL (port) % 8;} while (0) /* Maximum number of port types. */ #define SCM_I_MAX_PORT_TYPE_COUNT 256 @@ -184,8 +183,8 @@ typedef struct scm_t_ptob_descriptor int (*fill_input) (SCM port); int (*input_waiting) (SCM port); - off_t (*seek) (SCM port, off_t OFFSET, int WHENCE); - void (*truncate) (SCM port, off_t length); + scm_t_off (*seek) (SCM port, scm_t_off OFFSET, int WHENCE); + void (*truncate) (SCM port, scm_t_off length); } scm_t_ptob_descriptor; @@ -222,12 +221,12 @@ SCM_API void scm_set_port_end_input (scm_t_bits tc, void (*end_input) (SCM port, int offset)); SCM_API void scm_set_port_seek (scm_t_bits tc, - off_t (*seek) (SCM port, - off_t OFFSET, - int WHENCE)); + scm_t_off (*seek) (SCM port, + scm_t_off OFFSET, + int WHENCE)); SCM_API void scm_set_port_truncate (scm_t_bits tc, void (*truncate) (SCM port, - off_t length)); + scm_t_off length)); SCM_API void scm_set_port_input_waiting (scm_t_bits tc, int (*input_waiting) (SCM)); SCM_API SCM scm_char_ready_p (SCM port); size_t scm_take_from_input_buffers (SCM port, char *dest, size_t read_len); @@ -269,6 +268,9 @@ SCM_API SCM scm_read_char (SCM port); SCM_API size_t scm_c_read (SCM port, void *buffer, size_t size); SCM_API void scm_c_write (SCM port, const void *buffer, size_t size); SCM_API void scm_lfwrite (const char *ptr, size_t size, SCM port); +SCM_INTERNAL void scm_lfwrite_str (SCM str, SCM port); +SCM_INTERNAL void scm_lfwrite_substr (SCM str, size_t start, size_t end, + SCM port); SCM_API void scm_flush (SCM port); SCM_API void scm_end_input (SCM port); SCM_API int scm_fill_input (SCM port); diff --git a/libguile/posix.c b/libguile/posix.c index b5082fa0a..8f2990436 100644 --- a/libguile/posix.c +++ b/libguile/posix.c @@ -1,18 +1,19 @@ /* Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ @@ -21,6 +22,7 @@ # include #endif +#include #include #include @@ -33,6 +35,7 @@ #include "libguile/srfi-13.h" #include "libguile/srfi-14.h" #include "libguile/vectors.h" +#include "libguile/values.h" #include "libguile/lang.h" #include "libguile/validate.h" @@ -99,8 +102,6 @@ extern char *ttyname(); #include -extern char ** environ; - #ifdef HAVE_GRP_H #include #endif @@ -136,13 +137,7 @@ extern char ** environ; # include #endif -#if HAVE_SYS_FILE_H -# include -#endif - -#if HAVE_CRT_EXTERNS_H -#include /* for Darwin _NSGetEnviron */ -#endif +#include /* from Gnulib */ /* Some Unix systems don't define these. CPP hair is dangerous, but this seems safe enough... */ @@ -196,13 +191,6 @@ int sethostname (char *name, size_t namelen); -/* On Apple Darwin in a shared library there's no "environ" to access - directly, instead the address of that variable must be obtained with - _NSGetEnviron(). */ -#if HAVE__NSGETENVIRON && defined (PIC) -#define environ (*_NSGetEnviron()) -#endif - /* Two often used patterns @@ -463,6 +451,179 @@ SCM_DEFINE (scm_setgrent, "setgr", 0, 1, 0, #endif /* HAVE_GETGRENT */ +#ifdef HAVE_GETRLIMIT +#ifdef RLIMIT_AS +SCM_SYMBOL (sym_as, "as"); +#endif +#ifdef RLIMIT_CORE +SCM_SYMBOL (sym_core, "core"); +#endif +#ifdef RLIMIT_CPU +SCM_SYMBOL (sym_cpu, "cpu"); +#endif +#ifdef RLIMIT_DATA +SCM_SYMBOL (sym_data, "data"); +#endif +#ifdef RLIMIT_FSIZE +SCM_SYMBOL (sym_fsize, "fsize"); +#endif +#ifdef RLIMIT_MEMLOCK +SCM_SYMBOL (sym_memlock, "memlock"); +#endif +#ifdef RLIMIT_MSGQUEUE +SCM_SYMBOL (sym_msgqueue, "msgqueue"); +#endif +#ifdef RLIMIT_NICE +SCM_SYMBOL (sym_nice, "nice"); +#endif +#ifdef RLIMIT_NOFILE +SCM_SYMBOL (sym_nofile, "nofile"); +#endif +#ifdef RLIMIT_NPROC +SCM_SYMBOL (sym_nproc, "nproc"); +#endif +#ifdef RLIMIT_RSS +SCM_SYMBOL (sym_rss, "rss"); +#endif +#ifdef RLIMIT_RTPRIO +SCM_SYMBOL (sym_rtprio, "rtprio"); +#endif +#ifdef RLIMIT_RTPRIO +SCM_SYMBOL (sym_rttime, "rttime"); +#endif +#ifdef RLIMIT_SIGPENDING +SCM_SYMBOL (sym_sigpending, "sigpending"); +#endif +#ifdef RLIMIT_STACK +SCM_SYMBOL (sym_stack, "stack"); +#endif + +static int +scm_to_resource (SCM s, const char *func, int pos) +{ + if (scm_is_number (s)) + return scm_to_int (s); + + SCM_ASSERT_TYPE (scm_is_symbol (s), s, pos, func, "symbol"); + +#ifdef RLIMIT_AS + if (s == sym_as) + return RLIMIT_AS; +#endif +#ifdef RLIMIT_CORE + if (s == sym_core) + return RLIMIT_CORE; +#endif +#ifdef RLIMIT_CPU + if (s == sym_cpu) + return RLIMIT_CPU; +#endif +#ifdef RLIMIT_DATA + if (s == sym_data) + return RLIMIT_DATA; +#endif +#ifdef RLIMIT_FSIZE + if (s == sym_fsize) + return RLIMIT_FSIZE; +#endif +#ifdef RLIMIT_MEMLOCK + if (s == sym_memlock) + return RLIMIT_MEMLOCK; +#endif +#ifdef RLIMIT_MSGQUEUE + if (s == sym_msgqueue) + return RLIMIT_MSGQUEUE; +#endif +#ifdef RLIMIT_NICE + if (s == sym_nice) + return RLIMIT_NICE; +#endif +#ifdef RLIMIT_NOFILE + if (s == sym_nofile) + return RLIMIT_NOFILE; +#endif +#ifdef RLIMIT_NPROC + if (s == sym_nproc) + return RLIMIT_NPROC; +#endif +#ifdef RLIMIT_RSS + if (s == sym_rss) + return RLIMIT_RSS; +#endif +#ifdef RLIMIT_RTPRIO + if (s == sym_rtprio) + return RLIMIT_RTPRIO; +#endif +#ifdef RLIMIT_RTPRIO + if (s == sym_rttime) + return RLIMIT_RTPRIO; +#endif +#ifdef RLIMIT_SIGPENDING + if (s == sym_sigpending) + return RLIMIT_SIGPENDING; +#endif +#ifdef RLIMIT_STACK + if (s == sym_stack) + return RLIMIT_STACK; +#endif + + scm_misc_error (func, "invalid rlimit resource ~A", scm_list_1 (s)); + return 0; +} + +SCM_DEFINE (scm_getrlimit, "getrlimit", 1, 0, 0, + (SCM resource), + "Get a resource limit for this process. @var{resource} identifies the resource,\n" + "either as an integer or as a symbol. For example, @code{(getrlimit 'stack)}\n" + "gets the limits associated with @code{RLIMIT_STACK}.\n\n" + "@code{getrlimit} returns two values, the soft and the hard limit. If no\n" + "limit is set for the resource in question, the returned limit will be @code{#f}.") +#define FUNC_NAME s_scm_getrlimit +{ + int iresource; + struct rlimit lim = { 0, 0 }; + + iresource = scm_to_resource (resource, FUNC_NAME, 1); + + if (getrlimit (iresource, &lim) != 0) + scm_syserror (FUNC_NAME); + + return scm_values (scm_list_2 ((lim.rlim_cur == RLIM_INFINITY) ? SCM_BOOL_F + : scm_from_long (lim.rlim_cur), + (lim.rlim_max == RLIM_INFINITY) ? SCM_BOOL_F + : scm_from_long (lim.rlim_max))); +} +#undef FUNC_NAME + + +#ifdef HAVE_SETRLIMIT +SCM_DEFINE (scm_setrlimit, "setrlimit", 3, 0, 0, + (SCM resource, SCM soft, SCM hard), + "Set a resource limit for this process. @var{resource} identifies the resource,\n" + "either as an integer or as a symbol. @var{soft} and @var{hard} should be integers,\n" + "or @code{#f} to indicate no limit (i.e., @code{RLIM_INFINITY}).\n\n" + "For example, @code{(setrlimit 'stack 150000 300000)} sets the @code{RLIMIT_STACK}\n" + "limit to 150 kilobytes, with a hard limit of 300 kB.") +#define FUNC_NAME s_scm_setrlimit +{ + int iresource; + struct rlimit lim = { 0, 0 }; + + iresource = scm_to_resource (resource, FUNC_NAME, 1); + + lim.rlim_cur = (soft == SCM_BOOL_F) ? RLIM_INFINITY : scm_to_long (soft); + lim.rlim_max = (hard == SCM_BOOL_F) ? RLIM_INFINITY : scm_to_long (hard); + + if (setrlimit (iresource, &lim) != 0) + scm_syserror (FUNC_NAME); + + return SCM_UNSPECIFIED; +} +#undef FUNC_NAME +#endif /* HAVE_SETRLIMIT */ +#endif /* HAVE_GETRLIMIT */ + + SCM_DEFINE (scm_kill, "kill", 2, 0, 0, (SCM pid, SCM sig), "Sends a signal to the specified process or group of processes.\n\n" @@ -1311,98 +1472,13 @@ SCM_DEFINE (scm_putenv, "putenv", 1, 0, 0, int rv; char *c_str = scm_to_locale_string (str); - if (strchr (c_str, '=') == NULL) - { - /* We want no "=" in the argument to mean remove the variable from the - environment, but not all putenv()s understand this, for example - FreeBSD 4.8 doesn't. Getting it happening everywhere is a bit - painful. What unsetenv() exists, we use that, of course. + /* Leave C_STR in the environment. */ - Traditionally putenv("NAME") removes a variable, for example that's - what we have to do on Solaris 9 (it doesn't have an unsetenv). + /* Gnulib's `putenv' module honors the semantics described above. */ + rv = putenv (c_str); + if (rv < 0) + SCM_SYSERROR; - But on DOS and on that DOS overlay manager thing called W-whatever, - putenv("NAME=") must be used (it too doesn't have an unsetenv). - - Supposedly on AIX a putenv("NAME") could cause a segfault, but also - supposedly AIX 5.3 and up has unsetenv() available so should be ok - with the latter there. - - For the moment we hard code the DOS putenv("NAME=") style under - __MINGW32__ and do the traditional everywhere else. Such - system-name tests are bad, of course. It'd be possible to use a - configure test when doing a a native build. For example GNU R has - such a test (see R_PUTENV_AS_UNSETENV in - https://svn.r-project.org/R/trunk/m4/R.m4). But when cross - compiling there'd want to be a guess, one probably based on the - system name (ie. mingw or not), thus landing back in basically the - present hard-coded situation. Another possibility for a cross - build would be to try "NAME" then "NAME=" at runtime, if that's not - too much like overkill. */ - -#if HAVE_UNSETENV - /* when unsetenv() exists then we use it */ - unsetenv (c_str); - free (c_str); -#elif defined (__MINGW32__) - /* otherwise putenv("NAME=") on DOS */ - int e; - size_t len = strlen (c_str); - char *ptr = scm_malloc (len + 2); - strcpy (ptr, c_str); - strcpy (ptr+len, "="); - rv = putenv (ptr); - e = errno; free (ptr); free (c_str); errno = e; - if (rv < 0) - SCM_SYSERROR; -#else - /* otherwise traditional putenv("NAME") */ - rv = putenv (c_str); - if (rv < 0) - SCM_SYSERROR; -#endif - } - else - { -#ifdef __MINGW32__ - /* If str is "FOO=", ie. attempting to set an empty string, then - we need to see if it's been successful. On MINGW, "FOO=" - means remove FOO from the environment. As a workaround, we - set "FOO= ", ie. a space, and then modify the string returned - by getenv. It's not enough just to modify the string we set, - because MINGW putenv copies it. */ - - { - size_t len = strlen (c_str); - if (c_str[len-1] == '=') - { - char *ptr = scm_malloc (len+2); - strcpy (ptr, c_str); - strcpy (ptr+len, " "); - rv = putenv (ptr); - if (rv < 0) - { - int eno = errno; - free (c_str); - errno = eno; - SCM_SYSERROR; - } - /* truncate to just the name */ - c_str[len-1] = '\0'; - ptr = getenv (c_str); - if (ptr) - ptr[0] = '\0'; - return SCM_UNSPECIFIED; - } - } -#endif /* __MINGW32__ */ - - /* Leave c_str in the environment. */ - - rv = putenv (c_str); - if (rv < 0) - SCM_SYSERROR; - } return SCM_UNSPECIFIED; } #undef FUNC_NAME @@ -1668,6 +1744,11 @@ SCM_DEFINE (scm_getlogin, "getlogin", 0, 0, 0, #endif /* HAVE_GETLOGIN */ #if HAVE_CUSERID + +# if !HAVE_DECL_CUSERID +extern char *cuserid (char *); +# endif + SCM_DEFINE (scm_cuserid, "cuserid", 0, 0, 0, (void), "Return a string containing a user name associated with the\n" @@ -1777,73 +1858,6 @@ SCM_DEFINE (scm_getpass, "getpass", 1, 0, 0, #undef FUNC_NAME #endif /* HAVE_GETPASS */ -/* Wrapper function for flock() support under M$-Windows. */ -#ifdef __MINGW32__ -# include -# include -# include -# ifndef _LK_UNLCK - /* Current MinGW package fails to define this. *sigh* */ -# define _LK_UNLCK 0 -# endif -# define LOCK_EX 1 -# define LOCK_UN 2 -# define LOCK_SH 4 -# define LOCK_NB 8 - -static int flock (int fd, int operation) -{ - long pos, len; - int ret, err; - - /* Disable invalid arguments. */ - if (((operation & (LOCK_EX | LOCK_SH)) == (LOCK_EX | LOCK_SH)) || - ((operation & (LOCK_EX | LOCK_UN)) == (LOCK_EX | LOCK_UN)) || - ((operation & (LOCK_SH | LOCK_UN)) == (LOCK_SH | LOCK_UN))) - { - errno = EINVAL; - return -1; - } - - /* Determine mode of operation and discard unsupported ones. */ - if (operation == (LOCK_NB | LOCK_EX)) - operation = _LK_NBLCK; - else if (operation & LOCK_UN) - operation = _LK_UNLCK; - else if (operation == LOCK_EX) - operation = _LK_LOCK; - else - { - errno = EINVAL; - return -1; - } - - /* Save current file pointer and seek to beginning. */ - if ((pos = lseek (fd, 0, SEEK_CUR)) == -1 || (len = filelength (fd)) == -1) - return -1; - lseek (fd, 0L, SEEK_SET); - - /* Deadlock if necessary. */ - do - { - ret = _locking (fd, operation, len); - } - while (ret == -1 && errno == EDEADLOCK); - - /* Produce meaningful error message. */ - if (errno == EACCES && operation == _LK_NBLCK) - err = EDEADLOCK; - else - err = errno; - - /* Return to saved file position pointer. */ - lseek (fd, pos, SEEK_SET); - errno = err; - return ret; -} -#endif /* __MINGW32__ */ - -#if HAVE_FLOCK || defined (__MINGW32__) SCM_DEFINE (scm_flock, "flock", 2, 0, 0, (SCM file, SCM operation), "Apply or remove an advisory lock on an open file.\n" @@ -1887,7 +1901,6 @@ SCM_DEFINE (scm_flock, "flock", 2, 0, 0, return SCM_UNSPECIFIED; } #undef FUNC_NAME -#endif /* HAVE_FLOCK */ #if HAVE_SETHOSTNAME SCM_DEFINE (scm_sethostname, "sethostname", 1, 0, 0, diff --git a/libguile/posix.h b/libguile/posix.h index 34e1fc77f..4d057643c 100644 --- a/libguile/posix.h +++ b/libguile/posix.h @@ -6,18 +6,19 @@ /* Copyright (C) 1995,1996,1997,1998,2000,2001, 2003, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ @@ -41,6 +42,8 @@ SCM_API SCM scm_getpwuid (SCM user); SCM_API SCM scm_setpwent (SCM arg); SCM_API SCM scm_getgrgid (SCM name); SCM_API SCM scm_setgrent (SCM arg); +SCM_API SCM scm_getrlimit (SCM resource); +SCM_API SCM scm_setrlimit (SCM resource, SCM soft, SCM hard); SCM_API SCM scm_kill (SCM pid, SCM sig); SCM_API SCM scm_waitpid (SCM pid, SCM options); SCM_API SCM scm_status_exit_val (SCM status); diff --git a/libguile/print.c b/libguile/print.c index 1852cf19a..7a4aaa3ca 100644 --- a/libguile/print.c +++ b/libguile/print.c @@ -1,18 +1,19 @@ /* Copyright (C) 1995-1999,2000,2001, 2002, 2003, 2004, 2006, 2008, 2009 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ @@ -22,6 +23,8 @@ #endif #include +#include +#include #include "libguile/_scm.h" #include "libguile/chars.h" @@ -435,21 +438,33 @@ iprin1 (SCM exp, SCM port, scm_print_state *pstate) case scm_tc3_imm24: if (SCM_CHARP (exp)) { - long i = SCM_CHAR (exp); + scm_t_wchar i = SCM_CHAR (exp); + const char *name; if (SCM_WRITINGP (pstate)) { scm_puts ("#\\", port); - if ((i >= 0) && (i <= ' ') && scm_charnames[i]) - scm_puts (scm_charnames[i], port); -#ifndef EBCDIC - else if (i == '\177') - scm_puts (scm_charnames[scm_n_charnames - 1], port); -#endif - else if (i < 0 || i > '\177') - scm_intprint (i, 8, port); - else - scm_putc (i, port); + name = scm_i_charname (exp); + if (name != NULL) + scm_puts (name, port); + else if (uc_is_general_category_withtable (i, UC_CATEGORY_MASK_L + | UC_CATEGORY_MASK_M + | UC_CATEGORY_MASK_N + | UC_CATEGORY_MASK_P + | UC_CATEGORY_MASK_S)) + /* Print the character if is graphic character. */ + { + if (i<256) + /* Character is graphic. Print it. */ + scm_putc (i, port); + else + /* Character is graphic but unrepresentable in + this port's encoding. */ + scm_intprint (i, 8, port); + } + else + /* Character is a non-graphical character. */ + scm_intprint (i, 8, port); } else scm_putc (i, port); @@ -545,55 +560,113 @@ iprin1 (SCM exp, SCM port, scm_print_state *pstate) break; } break; - case scm_tc7_string: - if (SCM_WRITINGP (pstate)) - { - size_t i, j, len; - const char *data; + case scm_tc7_string: + if (SCM_WRITINGP (pstate)) + { + size_t i, j, len; + static char const hex[] = "0123456789abcdef"; + char buf[8]; - scm_putc ('"', port); - len = scm_i_string_length (exp); - data = scm_i_string_chars (exp); - for (i = 0, j = 0; i < len; ++i) - { - unsigned char ch = data[i]; - if ((ch < 32 && ch != '\n') || (127 <= ch && ch < 148)) - { - static char const hex[]="0123456789abcdef"; - char buf[4]; - scm_lfwrite (data+j, i-j, port); - buf[0] = '\\'; - buf[1] = 'x'; - buf[2] = hex [ch / 16]; - buf[3] = hex [ch % 16]; - scm_lfwrite (buf, 4, port); - data = scm_i_string_chars (exp); - j = i+1; - } - else if (ch == '"' || ch == '\\') - { - scm_lfwrite (data+j, i-j, port); - scm_putc ('\\', port); - data = scm_i_string_chars (exp); - j = i; - } - } - scm_lfwrite (data+j, i-j, port); - scm_putc ('"', port); - scm_remember_upto_here_1 (exp); - } - else - scm_lfwrite (scm_i_string_chars (exp), scm_i_string_length (exp), - port); - scm_remember_upto_here_1 (exp); - break; + scm_putc ('"', port); + len = scm_i_string_length (exp); + for (i = 0; i < len; ++i) + { + scm_t_wchar ch = scm_i_string_ref (exp, i); + int printed = 0; + + if (ch == ' ' || ch == '\n') + { + scm_putc (ch, port); + printed = 1; + } + else if (ch == '"' || ch == '\\') + { + scm_putc ('\\', port); + scm_i_charprint (ch, port); + printed = 1; + } + else + if (uc_is_general_category_withtable + (ch, + UC_CATEGORY_MASK_L | UC_CATEGORY_MASK_M | + UC_CATEGORY_MASK_N | UC_CATEGORY_MASK_P | + UC_CATEGORY_MASK_S)) + { + /* Print the character since it is a graphic + character. */ + scm_t_wchar *wbuf; + SCM wstr = scm_i_make_wide_string (1, &wbuf); + char *buf; + size_t len; + + wbuf[0] = ch; + + buf = u32_conv_to_encoding ("ISO-8859-1", + iconveh_error, + (scm_t_uint32 *) wbuf, + 1, NULL, NULL, &len); + if (buf != NULL) + { + /* Character is graphic and representable in + this encoding. Print it. */ + scm_lfwrite_str (wstr, port); + free (buf); + printed = 1; + } + } + + if (!printed) + { + /* Character is graphic but unrepresentable in + this port's encoding or is not graphic. */ + if (ch <= 0xFF) + { + buf[0] = '\\'; + buf[1] = 'x'; + buf[2] = hex[ch / 16]; + buf[3] = hex[ch % 16]; + scm_lfwrite (buf, 4, port); + } + else if (ch <= 0xFFFF) + { + buf[0] = '\\'; + buf[1] = 'u'; + buf[2] = hex[(ch & 0xF000) >> 12]; + buf[3] = hex[(ch & 0xF00) >> 8]; + buf[4] = hex[(ch & 0xF0) >> 4]; + buf[5] = hex[(ch & 0xF)]; + scm_lfwrite (buf, 6, port); + j = i + 1; + } + else if (ch > 0xFFFF) + { + buf[0] = '\\'; + buf[1] = 'U'; + buf[2] = hex[(ch & 0xF00000) >> 20]; + buf[3] = hex[(ch & 0xF0000) >> 16]; + buf[4] = hex[(ch & 0xF000) >> 12]; + buf[5] = hex[(ch & 0xF00) >> 8]; + buf[6] = hex[(ch & 0xF0) >> 4]; + buf[7] = hex[(ch & 0xF)]; + scm_lfwrite (buf, 8, port); + j = i + 1; + } + } + } + scm_putc ('"', port); + scm_remember_upto_here_1 (exp); + } + else + scm_lfwrite (scm_i_string_chars (exp), scm_i_string_length (exp), + port); + scm_remember_upto_here_1 (exp); + break; case scm_tc7_symbol: if (scm_i_symbol_is_interned (exp)) { scm_print_symbol_name (scm_i_symbol_chars (exp), - scm_i_symbol_length (exp), - port); + scm_i_symbol_length (exp), port); scm_remember_upto_here_1 (exp); } else @@ -668,7 +741,7 @@ iprin1 (SCM exp, SCM port, scm_print_state *pstate) ? "#', port); break; @@ -763,6 +836,17 @@ scm_prin1 (SCM exp, SCM port, int writingp) } } +/* Print a character. + */ +void +scm_i_charprint (scm_t_uint32 ch, SCM port) +{ + scm_t_wchar *wbuf; + SCM wstr = scm_i_make_wide_string (1, &wbuf); + + wbuf[0] = ch; + scm_lfwrite_str (wstr, port); +} /* Print an integer. */ diff --git a/libguile/print.h b/libguile/print.h index 8974a7554..00648efc1 100644 --- a/libguile/print.h +++ b/libguile/print.h @@ -6,18 +6,19 @@ /* Copyright (C) 1995,1996,1998,2000,2001, 2003, 2004, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ @@ -76,6 +77,7 @@ SCM_API SCM scm_print_options (SCM setting); SCM_API SCM scm_make_print_state (void); SCM_API void scm_free_print_state (SCM print_state); SCM_INTERNAL SCM scm_i_port_with_print_state (SCM port, SCM print_state); +SCM_INTERNAL void scm_i_charprint (scm_t_uint32 c, SCM port); SCM_API void scm_intprint (scm_t_intmax n, int radix, SCM port); SCM_API void scm_uintprint (scm_t_uintmax n, int radix, SCM port); SCM_API void scm_ipruk (char *hdr, SCM ptr, SCM port); diff --git a/libguile/private-gc.h b/libguile/private-gc.h index b38addebd..38d953f3c 100644 --- a/libguile/private-gc.h +++ b/libguile/private-gc.h @@ -1,21 +1,22 @@ /* * private-gc.h - private declarations for garbage collection. * - * Copyright (C) 2002, 03, 04, 05, 06, 07, 08 Free Software Foundation, Inc. + * Copyright (C) 2002, 03, 04, 05, 06, 07, 08, 09 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ #ifndef PRIVATE_GC @@ -103,11 +104,10 @@ typedef enum { return_on_error, abort_on_error } policy_on_error; gc-mark */ -/* this can be used to ensure that set/clear gc marks only happen when - allowed. */ -int scm_i_marking; +/* Non-zero while in the mark phase. */ +SCM_INTERNAL int scm_i_marking; -void scm_mark_all (void); +SCM_INTERNAL void scm_mark_all (void); extern long int scm_i_deprecated_memory_return; extern long int scm_i_find_heap_calls; diff --git a/libguile/private-options.h b/libguile/private-options.h index eeaf0c17b..ffb699bee 100644 --- a/libguile/private-options.h +++ b/libguile/private-options.h @@ -7,18 +7,19 @@ * Copyright (C) 2007 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ #ifndef PRIVATE_OPTIONS diff --git a/libguile/procprop.c b/libguile/procprop.c index db16834c5..df96eaad4 100644 --- a/libguile/procprop.c +++ b/libguile/procprop.c @@ -1,18 +1,19 @@ /* Copyright (C) 1995,1996,1998,2000,2001,2003,2004, 2006, 2008, 2009 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/procprop.h b/libguile/procprop.h index bf27dba0a..04cd38442 100644 --- a/libguile/procprop.h +++ b/libguile/procprop.h @@ -6,18 +6,19 @@ /* Copyright (C) 1995,1996,1998,2000, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/procs.c b/libguile/procs.c index c695668e2..b67bfd90b 100644 --- a/libguile/procs.c +++ b/libguile/procs.c @@ -1,18 +1,19 @@ /* Copyright (C) 1995,1996,1997,1999,2000,2001, 2006, 2008, 2009 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ @@ -45,15 +46,19 @@ SCM scm_c_make_subr (const char *name, long type, SCM (*fcn) ()) { register SCM z; + SCM sname; SCM *meta_info; meta_info = scm_gc_malloc (2 * sizeof (*meta_info), "subr meta-info"); - meta_info[0] = scm_from_locale_symbol (name); + sname = scm_from_locale_symbol (name); + meta_info[0] = sname; meta_info[1] = SCM_EOL; /* properties */ z = scm_double_cell ((scm_t_bits) type, (scm_t_bits) fcn, 0 /* generic */, (scm_t_bits) meta_info); + scm_remember_upto_here_1 (sname); + return z; } @@ -61,7 +66,7 @@ SCM scm_c_define_subr (const char *name, long type, SCM (*fcn) ()) { SCM subr = scm_c_make_subr (name, type, fcn); - scm_define (SCM_SNAME (subr), subr); + scm_define (SCM_SUBR_NAME (subr), subr); return subr; } @@ -79,7 +84,7 @@ scm_c_define_subr_with_generic (const char *name, long type, SCM (*fcn) (), SCM *gf) { SCM subr = scm_c_make_subr_with_generic (name, type, fcn, gf); - scm_define (SCM_SNAME (subr), subr); + scm_define (SCM_SUBR_NAME (subr), subr); return subr; } @@ -223,7 +228,7 @@ SCM_DEFINE (scm_make_procedure_with_setter, "make-procedure-with-setter", 2, 0, lookup */ switch (SCM_TYP7 (procedure)) { case scm_tcs_subrs: - name = SCM_SNAME (procedure); + name = SCM_SUBR_NAME (procedure); break; default: name = scm_procedure_property (procedure, scm_sym_name); diff --git a/libguile/procs.h b/libguile/procs.h index 3ccf1ee33..469b735d9 100644 --- a/libguile/procs.h +++ b/libguile/procs.h @@ -6,18 +6,19 @@ /* Copyright (C) 1995,1996,1998,1999,2000,2001, 2006, 2008, 2009 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ @@ -31,7 +32,7 @@ */ #define SCM_SUBR_META_INFO(x) ((SCM *) SCM_CELL_WORD_3 (x)) -#define SCM_SNAME(x) (SCM_SUBR_META_INFO (x) [0]) +#define SCM_SUBR_NAME(x) (SCM_SUBR_META_INFO (x) [0]) #define SCM_SUBRF(x) ((SCM (*)()) SCM_CELL_WORD_1 (x)) #define SCM_DSUBRF(x) ((double (*)()) SCM_CELL_WORD_1 (x)) #define SCM_SUBR_PROPS(x) (SCM_SUBR_META_INFO (x) [1]) diff --git a/libguile/programs.c b/libguile/programs.c index 1fcfc54c8..d62a3a085 100644 --- a/libguile/programs.c +++ b/libguile/programs.c @@ -1,49 +1,27 @@ -/* Copyright (C) 2001 Free Software Foundation, Inc. - * - * 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 2, or (at your option) - * any later version. +/* Copyright (C) 2001, 2009 Free Software Foundation, Inc. * - * 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 software; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307 USA + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * As a special exception, the Free Software Foundation gives permission - * for additional uses of the text contained in its release of GUILE. + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * The exception is that, if you link the GUILE library with other files - * to produce an executable, this does not by itself cause the - * resulting executable to be covered by the GNU General Public License. - * Your use of that executable is in no way restricted on account of - * linking the GUILE library code into it. - * - * This exception does not however invalidate any other reasons why - * the executable file might be covered by the GNU General Public License. - * - * This exception applies only to the code released by the - * Free Software Foundation under the name GUILE. If you copy - * code from other Free Software Foundation releases into a copy of - * GUILE, as the General Public License permits, the exception does - * not apply to the code that you add in this way. To avoid misleading - * anyone as to the status of such modified files, you must delete - * this exception notice from them. - * - * If you write modifications of your own for GUILE, it is your choice - * whether to permit this exception to apply to your modifications. - * If you do not wish that, delete this exception notice. */ + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ #if HAVE_CONFIG_H # include #endif #include +#include "_scm.h" #include "vm-bootstrap.h" #include "instructions.h" #include "modules.h" @@ -58,7 +36,7 @@ scm_t_bits scm_tc16_program; static SCM write_program = SCM_BOOL_F; SCM_DEFINE (scm_make_program, "make-program", 1, 2, 0, - (SCM objcode, SCM objtable, SCM external), + (SCM objcode, SCM objtable, SCM free_variables), "") #define FUNC_NAME s_scm_make_program { @@ -67,18 +45,12 @@ SCM_DEFINE (scm_make_program, "make-program", 1, 2, 0, objtable = SCM_BOOL_F; else if (scm_is_true (objtable)) SCM_VALIDATE_VECTOR (2, objtable); - if (SCM_UNLIKELY (SCM_UNBNDP (external))) - external = SCM_EOL; - else - /* FIXME: currently this test is quite expensive (can be 2-3% of total - execution time in programs that make many closures). We could remove it, - yes, but we'd get much better gains if we used some other method, like - just capturing the variables that we need instead of all heap-allocated - variables. Dunno. Keeping the check for now, as it's a user-callable - function, and inlining the op in the vm's make-closure operation. */ - SCM_VALIDATE_LIST (3, external); + if (SCM_UNLIKELY (SCM_UNBNDP (free_variables))) + free_variables = SCM_BOOL_F; + else if (free_variables != SCM_BOOL_F) + SCM_VALIDATE_VECTOR (3, free_variables); - SCM_RETURN_NEWSMOB3 (scm_tc16_program, objcode, objtable, external); + SCM_RETURN_NEWSMOB3 (scm_tc16_program, objcode, objtable, free_variables); } #undef FUNC_NAME @@ -163,10 +135,9 @@ SCM_DEFINE (scm_program_arity, "program-arity", 1, 0, 0, SCM_VALIDATE_PROGRAM (1, program); p = SCM_PROGRAM_DATA (program); - return SCM_LIST4 (SCM_I_MAKINUM (p->nargs), - SCM_I_MAKINUM (p->nrest), - SCM_I_MAKINUM (p->nlocs), - SCM_I_MAKINUM (p->nexts)); + return scm_list_3 (SCM_I_MAKINUM (p->nargs), + SCM_I_MAKINUM (p->nrest), + SCM_I_MAKINUM (p->nlocs)); } #undef FUNC_NAME @@ -203,7 +174,7 @@ SCM_DEFINE (scm_program_meta, "program-meta", 1, 0, 0, metaobj = scm_objcode_meta (SCM_PROGRAM_OBJCODE (program)); if (scm_is_true (metaobj)) - return scm_make_program (metaobj, SCM_BOOL_F, SCM_EOL); + return scm_make_program (metaobj, SCM_BOOL_F, SCM_BOOL_F); else return SCM_BOOL_F; } @@ -312,26 +283,13 @@ scm_c_program_source (SCM program, size_t ip) return source; /* (addr . (filename . (line . column))) */ } -SCM_DEFINE (scm_program_external, "program-external", 1, 0, 0, +SCM_DEFINE (scm_program_free_variables, "program-free-variables", 1, 0, 0, (SCM program), "") -#define FUNC_NAME s_scm_program_external +#define FUNC_NAME s_scm_program_free_variables { SCM_VALIDATE_PROGRAM (1, program); - return SCM_PROGRAM_EXTERNALS (program); -} -#undef FUNC_NAME - -SCM_DEFINE (scm_program_external_set_x, "program-external-set!", 2, 0, 0, - (SCM program, SCM external), - "Modify the list of closure variables of @var{program} (for " - "debugging purposes).") -#define FUNC_NAME s_scm_program_external_set_x -{ - SCM_VALIDATE_PROGRAM (1, program); - SCM_VALIDATE_LIST (2, external); - SCM_PROGRAM_EXTERNALS (program) = external; - return SCM_UNSPECIFIED; + return SCM_PROGRAM_FREE_VARIABLES (program); } #undef FUNC_NAME @@ -357,6 +315,8 @@ scm_bootstrap_programs (void) scm_smobs[SCM_TC2SMOBNUM (scm_tc16_program)].apply_1 = program_apply_1; scm_smobs[SCM_TC2SMOBNUM (scm_tc16_program)].apply_2 = program_apply_2; scm_set_smob_print (scm_tc16_program, program_print); + scm_c_register_extension ("libguile", "scm_init_programs", + (scm_t_extension_init_func)scm_init_programs, NULL); } void diff --git a/libguile/programs.h b/libguile/programs.h index 68a6936a2..040e8ea2c 100644 --- a/libguile/programs.h +++ b/libguile/programs.h @@ -1,43 +1,20 @@ -/* Copyright (C) 2001 Free Software Foundation, Inc. - * - * 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 2, or (at your option) - * any later version. +/* Copyright (C) 2001, 2009 Free Software Foundation, Inc. * - * 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 software; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307 USA + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * As a special exception, the Free Software Foundation gives permission - * for additional uses of the text contained in its release of GUILE. + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * The exception is that, if you link the GUILE library with other files - * to produce an executable, this does not by itself cause the - * resulting executable to be covered by the GNU General Public License. - * Your use of that executable is in no way restricted on account of - * linking the GUILE library code into it. - * - * This exception does not however invalidate any other reasons why - * the executable file might be covered by the GNU General Public License. - * - * This exception applies only to the code released by the - * Free Software Foundation under the name GUILE. If you copy - * code from other Free Software Foundation releases into a copy of - * GUILE, as the General Public License permits, the exception does - * not apply to the code that you add in this way. To avoid misleading - * anyone as to the status of such modified files, you must delete - * this exception notice from them. - * - * If you write modifications of your own for GUILE, it is your choice - * whether to permit this exception to apply to your modifications. - * If you do not wish that, delete this exception notice. */ + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ #ifndef _SCM_PROGRAMS_H_ #define _SCM_PROGRAMS_H_ @@ -51,39 +28,38 @@ typedef unsigned char scm_byte_t; -extern scm_t_bits scm_tc16_program; +SCM_API scm_t_bits scm_tc16_program; #define SCM_F_PROGRAM_IS_BOOT (1<<0) #define SCM_PROGRAM_P(x) (SCM_SMOB_PREDICATE (scm_tc16_program, x)) #define SCM_PROGRAM_OBJCODE(x) (SCM_SMOB_OBJECT (x)) #define SCM_PROGRAM_OBJTABLE(x) (SCM_SMOB_OBJECT_2 (x)) -#define SCM_PROGRAM_EXTERNALS(x) (SCM_SMOB_OBJECT_3 (x)) +#define SCM_PROGRAM_FREE_VARIABLES(x) (SCM_SMOB_OBJECT_3 (x)) #define SCM_PROGRAM_DATA(x) (SCM_OBJCODE_DATA (SCM_PROGRAM_OBJCODE (x))) #define SCM_VALIDATE_PROGRAM(p,x) SCM_MAKE_VALIDATE (p, x, PROGRAM_P) #define SCM_PROGRAM_IS_BOOT(x) (SCM_SMOB_FLAGS (x) & SCM_F_PROGRAM_IS_BOOT) -extern SCM scm_make_program (SCM objcode, SCM objtable, SCM externals); +SCM_API SCM scm_make_program (SCM objcode, SCM objtable, SCM free_variables); -extern SCM scm_program_p (SCM obj); -extern SCM scm_program_base (SCM program); -extern SCM scm_program_arity (SCM program); -extern SCM scm_program_meta (SCM program); -extern SCM scm_program_bindings (SCM program); -extern SCM scm_program_sources (SCM program); -extern SCM scm_program_source (SCM program, SCM ip); -extern SCM scm_program_properties (SCM program); -extern SCM scm_program_name (SCM program); -extern SCM scm_program_objects (SCM program); -extern SCM scm_program_module (SCM program); -extern SCM scm_program_external (SCM program); -extern SCM scm_program_external_set_x (SCM program, SCM external); -extern SCM scm_program_objcode (SCM program); +SCM_API SCM scm_program_p (SCM obj); +SCM_API SCM scm_program_base (SCM program); +SCM_API SCM scm_program_arity (SCM program); +SCM_API SCM scm_program_meta (SCM program); +SCM_API SCM scm_program_bindings (SCM program); +SCM_API SCM scm_program_sources (SCM program); +SCM_API SCM scm_program_source (SCM program, SCM ip); +SCM_API SCM scm_program_properties (SCM program); +SCM_API SCM scm_program_name (SCM program); +SCM_API SCM scm_program_objects (SCM program); +SCM_API SCM scm_program_module (SCM program); +SCM_API SCM scm_program_free_variables (SCM program); +SCM_API SCM scm_program_objcode (SCM program); -extern SCM scm_c_program_source (SCM program, size_t ip); +SCM_API SCM scm_c_program_source (SCM program, size_t ip); -extern void scm_bootstrap_programs (void); -extern void scm_init_programs (void); +SCM_INTERNAL void scm_bootstrap_programs (void); +SCM_INTERNAL void scm_init_programs (void); #endif /* _SCM_PROGRAMS_H_ */ diff --git a/libguile/properties.c b/libguile/properties.c index 321dc9ec4..60ff2ff65 100644 --- a/libguile/properties.c +++ b/libguile/properties.c @@ -1,18 +1,19 @@ /* Copyright (C) 1995,1996,2000,2001, 2003, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/properties.h b/libguile/properties.h index 54feb01d9..efeaf3a59 100644 --- a/libguile/properties.h +++ b/libguile/properties.h @@ -6,18 +6,19 @@ /* Copyright (C) 1995,1996,1998,2000, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/pthread-threads.h b/libguile/pthread-threads.h index bd6d4854d..4f72a4293 100644 --- a/libguile/pthread-threads.h +++ b/libguile/pthread-threads.h @@ -6,18 +6,19 @@ /* Copyright (C) 2002, 2005, 2006 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/putenv.c b/libguile/putenv.c index 0ff33592a..cdc05dd7e 100644 --- a/libguile/putenv.c +++ b/libguile/putenv.c @@ -1,18 +1,19 @@ /* Copyright (C) 1991, 2000, 2001, 2004, 2005, 2006 Free Software Foundation, Inc. * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/r6rs-ports.c b/libguile/r6rs-ports.c new file mode 100644 index 000000000..e3aa99e16 --- /dev/null +++ b/libguile/r6rs-ports.c @@ -0,0 +1,1122 @@ +/* Copyright (C) 2009 Free Software Foundation, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#ifdef HAVE_UNISTD_H +# include +#endif + +#include +#include +#include + +#include "libguile/_scm.h" +#include "libguile/bytevectors.h" +#include "libguile/chars.h" +#include "libguile/eval.h" +#include "libguile/r6rs-ports.h" +#include "libguile/strings.h" +#include "libguile/validate.h" +#include "libguile/values.h" +#include "libguile/vectors.h" + + + +/* Unimplemented features. */ + + +/* Transoders are currently not implemented since Guile 1.8 is not + Unicode-capable. Thus, most of the code here assumes the use of the + binary transcoder. */ +static inline void +transcoders_not_implemented (void) +{ + fprintf (stderr, "%s: warning: transcoders not implemented\n", + PACKAGE_NAME); +} + + +/* End-of-file object. */ + +SCM_DEFINE (scm_eof_object, "eof-object", 0, 0, 0, + (void), + "Return the end-of-file object.") +#define FUNC_NAME s_scm_eof_object +{ + return (SCM_EOF_VAL); +} +#undef FUNC_NAME + + +/* Input ports. */ + +#ifndef MIN +# define MIN(a,b) ((a) < (b) ? (a) : (b)) +#endif + +/* Bytevector input ports or "bip" for short. */ +static scm_t_bits bytevector_input_port_type = 0; + +static inline SCM +make_bip (SCM bv) +{ + SCM port; + char *c_bv; + unsigned c_len; + scm_t_port *c_port; + const unsigned long mode_bits = SCM_OPN | SCM_RDNG; + + port = scm_new_port_table_entry (bytevector_input_port_type); + + /* Prevent BV from being GC'd. */ + SCM_SETSTREAM (port, SCM_UNPACK (bv)); + + /* Have the port directly access the bytevector. */ + c_bv = (char *) SCM_BYTEVECTOR_CONTENTS (bv); + c_len = SCM_BYTEVECTOR_LENGTH (bv); + + c_port = SCM_PTAB_ENTRY (port); + c_port->read_pos = c_port->read_buf = (unsigned char *) c_bv; + c_port->read_end = (unsigned char *) c_bv + c_len; + c_port->read_buf_size = c_len; + + /* Mark PORT as open, readable and unbuffered (hmm, how elegant...). */ + SCM_SET_CELL_TYPE (port, bytevector_input_port_type | mode_bits); + + return port; +} + +static SCM +bip_mark (SCM port) +{ + /* Mark the underlying bytevector. */ + return (SCM_PACK (SCM_STREAM (port))); +} + +static int +bip_fill_input (SCM port) +{ + int result; + scm_t_port *c_port = SCM_PTAB_ENTRY (port); + + if (c_port->read_pos >= c_port->read_end) + result = EOF; + else + result = (int) *c_port->read_pos; + + return result; +} + +static scm_t_off +bip_seek (SCM port, scm_t_off offset, int whence) +#define FUNC_NAME "bip_seek" +{ + scm_t_off c_result = 0; + scm_t_port *c_port = SCM_PTAB_ENTRY (port); + + switch (whence) + { + case SEEK_CUR: + offset += c_port->read_pos - c_port->read_buf; + /* Fall through. */ + + case SEEK_SET: + if (c_port->read_buf + offset < c_port->read_end) + { + c_port->read_pos = c_port->read_buf + offset; + c_result = offset; + } + else + scm_out_of_range (FUNC_NAME, scm_from_int (offset)); + break; + + case SEEK_END: + if (c_port->read_end - offset >= c_port->read_buf) + { + c_port->read_pos = c_port->read_end - offset; + c_result = c_port->read_pos - c_port->read_buf; + } + else + scm_out_of_range (FUNC_NAME, scm_from_int (offset)); + break; + + default: + scm_wrong_type_arg_msg (FUNC_NAME, 0, port, + "invalid `seek' parameter"); + } + + return c_result; +} +#undef FUNC_NAME + + +/* Instantiate the bytevector input port type. */ +static inline void +initialize_bytevector_input_ports (void) +{ + bytevector_input_port_type = + scm_make_port_type ("r6rs-bytevector-input-port", bip_fill_input, + NULL); + + scm_set_port_mark (bytevector_input_port_type, bip_mark); + scm_set_port_seek (bytevector_input_port_type, bip_seek); +} + + +SCM_DEFINE (scm_open_bytevector_input_port, + "open-bytevector-input-port", 1, 1, 0, + (SCM bv, SCM transcoder), + "Return an input port whose contents are drawn from " + "bytevector @var{bv}.") +#define FUNC_NAME s_scm_open_bytevector_input_port +{ + SCM_VALIDATE_BYTEVECTOR (1, bv); + if (!SCM_UNBNDP (transcoder) && !scm_is_false (transcoder)) + transcoders_not_implemented (); + + return (make_bip (bv)); +} +#undef FUNC_NAME + + +/* Custom binary ports. The following routines are shared by input and + output custom binary ports. */ + +#define SCM_CBP_GET_POSITION_PROC(_port) \ + SCM_SIMPLE_VECTOR_REF (SCM_PACK (SCM_STREAM (_port)), 1) +#define SCM_CBP_SET_POSITION_PROC(_port) \ + SCM_SIMPLE_VECTOR_REF (SCM_PACK (SCM_STREAM (_port)), 2) +#define SCM_CBP_CLOSE_PROC(_port) \ + SCM_SIMPLE_VECTOR_REF (SCM_PACK (SCM_STREAM (_port)), 3) + +static SCM +cbp_mark (SCM port) +{ + /* Mark the underlying method and object vector. */ + if (SCM_OPENP (port)) + return SCM_PACK (SCM_STREAM (port)); + else + return SCM_BOOL_F; +} + +static scm_t_off +cbp_seek (SCM port, scm_t_off offset, int whence) +#define FUNC_NAME "cbp_seek" +{ + SCM result; + scm_t_off c_result = 0; + + switch (whence) + { + case SEEK_CUR: + { + SCM get_position_proc; + + get_position_proc = SCM_CBP_GET_POSITION_PROC (port); + if (SCM_LIKELY (scm_is_true (get_position_proc))) + result = scm_call_0 (get_position_proc); + else + scm_wrong_type_arg_msg (FUNC_NAME, 0, port, + "R6RS custom binary port does not " + "support `port-position'"); + + offset += scm_to_int (result); + /* Fall through. */ + } + + case SEEK_SET: + { + SCM set_position_proc; + + set_position_proc = SCM_CBP_SET_POSITION_PROC (port); + if (SCM_LIKELY (scm_is_true (set_position_proc))) + result = scm_call_1 (set_position_proc, scm_from_int (offset)); + else + scm_wrong_type_arg_msg (FUNC_NAME, 0, port, + "R6RS custom binary port does not " + "support `set-port-position!'"); + + /* Assuming setting the position succeeded. */ + c_result = offset; + break; + } + + default: + /* `SEEK_END' cannot be supported. */ + scm_wrong_type_arg_msg (FUNC_NAME, 0, port, + "R6RS custom binary ports do not " + "support `SEEK_END'"); + } + + return c_result; +} +#undef FUNC_NAME + +static int +cbp_close (SCM port) +{ + SCM close_proc; + + close_proc = SCM_CBP_CLOSE_PROC (port); + if (scm_is_true (close_proc)) + /* Invoke the `close' thunk. */ + scm_call_0 (close_proc); + + return 1; +} + + +/* Custom binary input port ("cbip" for short). */ + +static scm_t_bits custom_binary_input_port_type = 0; + +/* Size of the buffer embedded in custom binary input ports. */ +#define CBIP_BUFFER_SIZE 4096 + +/* Return the bytevector associated with PORT. */ +#define SCM_CBIP_BYTEVECTOR(_port) \ + SCM_SIMPLE_VECTOR_REF (SCM_PACK (SCM_STREAM (_port)), 4) + +/* Return the various procedures of PORT. */ +#define SCM_CBIP_READ_PROC(_port) \ + SCM_SIMPLE_VECTOR_REF (SCM_PACK (SCM_STREAM (_port)), 0) + + +static inline SCM +make_cbip (SCM read_proc, SCM get_position_proc, + SCM set_position_proc, SCM close_proc) +{ + SCM port, bv, method_vector; + char *c_bv; + unsigned c_len; + scm_t_port *c_port; + const unsigned long mode_bits = SCM_OPN | SCM_RDNG; + + /* Use a bytevector as the underlying buffer. */ + c_len = CBIP_BUFFER_SIZE; + bv = scm_c_make_bytevector (c_len); + c_bv = (char *) SCM_BYTEVECTOR_CONTENTS (bv); + + /* Store the various methods and bytevector in a vector. */ + method_vector = scm_c_make_vector (5, SCM_BOOL_F); + SCM_SIMPLE_VECTOR_SET (method_vector, 4, bv); + SCM_SIMPLE_VECTOR_SET (method_vector, 0, read_proc); + SCM_SIMPLE_VECTOR_SET (method_vector, 1, get_position_proc); + SCM_SIMPLE_VECTOR_SET (method_vector, 2, set_position_proc); + SCM_SIMPLE_VECTOR_SET (method_vector, 3, close_proc); + + port = scm_new_port_table_entry (custom_binary_input_port_type); + + /* Attach it the method vector. */ + SCM_SETSTREAM (port, SCM_UNPACK (method_vector)); + + /* Have the port directly access the buffer (bytevector). */ + c_port = SCM_PTAB_ENTRY (port); + c_port->read_pos = c_port->read_buf = (unsigned char *) c_bv; + c_port->read_end = (unsigned char *) c_bv; + c_port->read_buf_size = c_len; + + /* Mark PORT as open, readable and unbuffered (hmm, how elegant...). */ + SCM_SET_CELL_TYPE (port, custom_binary_input_port_type | mode_bits); + + return port; +} + +static int +cbip_fill_input (SCM port) +#define FUNC_NAME "cbip_fill_input" +{ + int result; + scm_t_port *c_port = SCM_PTAB_ENTRY (port); + + again: + if (c_port->read_pos >= c_port->read_end) + { + /* Invoke the user's `read!' procedure. */ + unsigned c_octets; + SCM bv, read_proc, octets; + + /* Use the bytevector associated with PORT as the buffer passed to the + `read!' procedure, thereby avoiding additional allocations. */ + bv = SCM_CBIP_BYTEVECTOR (port); + read_proc = SCM_CBIP_READ_PROC (port); + + /* The assumption here is that C_PORT's internal buffer wasn't changed + behind our back. */ + assert (c_port->read_buf == + (unsigned char *) SCM_BYTEVECTOR_CONTENTS (bv)); + assert ((unsigned) c_port->read_buf_size + == SCM_BYTEVECTOR_LENGTH (bv)); + + octets = scm_call_3 (read_proc, bv, SCM_INUM0, + SCM_I_MAKINUM (CBIP_BUFFER_SIZE)); + c_octets = scm_to_uint (octets); + + c_port->read_pos = (unsigned char *) SCM_BYTEVECTOR_CONTENTS (bv); + c_port->read_end = (unsigned char *) c_port->read_pos + c_octets; + + if (c_octets > 0) + goto again; + else + result = EOF; + } + else + result = (int) *c_port->read_pos; + + return result; +} +#undef FUNC_NAME + + +SCM_DEFINE (scm_make_custom_binary_input_port, + "make-custom-binary-input-port", 5, 0, 0, + (SCM id, SCM read_proc, SCM get_position_proc, + SCM set_position_proc, SCM close_proc), + "Return a new custom binary input port whose input is drained " + "by invoking @var{read_proc} and passing it a bytevector, an " + "index where octets should be written, and an octet count.") +#define FUNC_NAME s_scm_make_custom_binary_input_port +{ + SCM_VALIDATE_STRING (1, id); + SCM_VALIDATE_PROC (2, read_proc); + + if (!scm_is_false (get_position_proc)) + SCM_VALIDATE_PROC (3, get_position_proc); + + if (!scm_is_false (set_position_proc)) + SCM_VALIDATE_PROC (4, set_position_proc); + + if (!scm_is_false (close_proc)) + SCM_VALIDATE_PROC (5, close_proc); + + return (make_cbip (read_proc, get_position_proc, set_position_proc, + close_proc)); +} +#undef FUNC_NAME + + +/* Instantiate the custom binary input port type. */ +static inline void +initialize_custom_binary_input_ports (void) +{ + custom_binary_input_port_type = + scm_make_port_type ("r6rs-custom-binary-input-port", + cbip_fill_input, NULL); + + scm_set_port_mark (custom_binary_input_port_type, cbp_mark); + scm_set_port_seek (custom_binary_input_port_type, cbp_seek); + scm_set_port_close (custom_binary_input_port_type, cbp_close); +} + + + +/* Binary input. */ + +/* We currently don't support specific binary input ports. */ +#define SCM_VALIDATE_BINARY_INPUT_PORT SCM_VALIDATE_OPINPORT + +SCM_DEFINE (scm_get_u8, "get-u8", 1, 0, 0, + (SCM port), + "Read an octet from @var{port}, a binary input port, " + "blocking as necessary.") +#define FUNC_NAME s_scm_get_u8 +{ + SCM result; + int c_result; + + SCM_VALIDATE_BINARY_INPUT_PORT (1, port); + + c_result = scm_getc (port); + if (c_result == EOF) + result = SCM_EOF_VAL; + else + result = SCM_I_MAKINUM ((unsigned char) c_result); + + return result; +} +#undef FUNC_NAME + +SCM_DEFINE (scm_lookahead_u8, "lookahead-u8", 1, 0, 0, + (SCM port), + "Like @code{get-u8} but does not update @var{port} to " + "point past the octet.") +#define FUNC_NAME s_scm_lookahead_u8 +{ + SCM result; + + SCM_VALIDATE_BINARY_INPUT_PORT (1, port); + + result = scm_peek_char (port); + if (SCM_CHARP (result)) + result = SCM_I_MAKINUM ((signed char) SCM_CHAR (result)); + else + result = SCM_EOF_VAL; + + return result; +} +#undef FUNC_NAME + +SCM_DEFINE (scm_get_bytevector_n, "get-bytevector-n", 2, 0, 0, + (SCM port, SCM count), + "Read @var{count} octets from @var{port}, blocking as " + "necessary and return a bytevector containing the octets " + "read. If fewer bytes are available, a bytevector smaller " + "than @var{count} is returned.") +#define FUNC_NAME s_scm_get_bytevector_n +{ + SCM result; + char *c_bv; + unsigned c_count; + size_t c_read; + + SCM_VALIDATE_BINARY_INPUT_PORT (1, port); + c_count = scm_to_uint (count); + + result = scm_c_make_bytevector (c_count); + c_bv = (char *) SCM_BYTEVECTOR_CONTENTS (result); + + if (SCM_LIKELY (c_count > 0)) + /* XXX: `scm_c_read ()' does not update the port position. */ + c_read = scm_c_read (port, c_bv, c_count); + else + /* Don't invoke `scm_c_read ()' since it may block. */ + c_read = 0; + + if ((c_read == 0) && (c_count > 0)) + { + if (SCM_EOF_OBJECT_P (scm_peek_char (port))) + result = SCM_EOF_VAL; + else + result = scm_null_bytevector; + } + else + { + if (c_read < c_count) + result = scm_c_shrink_bytevector (result, c_read); + } + + return result; +} +#undef FUNC_NAME + +SCM_DEFINE (scm_get_bytevector_n_x, "get-bytevector-n!", 4, 0, 0, + (SCM port, SCM bv, SCM start, SCM count), + "Read @var{count} bytes from @var{port} and store them " + "in @var{bv} starting at index @var{start}. Return either " + "the number of bytes actually read or the end-of-file " + "object.") +#define FUNC_NAME s_scm_get_bytevector_n_x +{ + SCM result; + char *c_bv; + unsigned c_start, c_count, c_len; + size_t c_read; + + SCM_VALIDATE_BINARY_INPUT_PORT (1, port); + SCM_VALIDATE_BYTEVECTOR (2, bv); + c_start = scm_to_uint (start); + c_count = scm_to_uint (count); + + c_bv = (char *) SCM_BYTEVECTOR_CONTENTS (bv); + c_len = SCM_BYTEVECTOR_LENGTH (bv); + + if (SCM_UNLIKELY (c_start + c_count > c_len)) + scm_out_of_range (FUNC_NAME, count); + + if (SCM_LIKELY (c_count > 0)) + c_read = scm_c_read (port, c_bv + c_start, c_count); + else + /* Don't invoke `scm_c_read ()' since it may block. */ + c_read = 0; + + if ((c_read == 0) && (c_count > 0)) + { + if (SCM_EOF_OBJECT_P (scm_peek_char (port))) + result = SCM_EOF_VAL; + else + result = SCM_I_MAKINUM (0); + } + else + result = scm_from_size_t (c_read); + + return result; +} +#undef FUNC_NAME + + +SCM_DEFINE (scm_get_bytevector_some, "get-bytevector-some", 1, 0, 0, + (SCM port), + "Read from @var{port}, blocking as necessary, until data " + "are available or and end-of-file is reached. Return either " + "a new bytevector containing the data read or the " + "end-of-file object.") +#define FUNC_NAME s_scm_get_bytevector_some +{ + /* Read at least one byte, unless the end-of-file is already reached, and + read while characters are available (buffered). */ + + SCM result; + char *c_bv; + unsigned c_len; + size_t c_total; + + SCM_VALIDATE_BINARY_INPUT_PORT (1, port); + + c_len = 4096; + c_bv = (char *) scm_gc_malloc (c_len, SCM_GC_BYTEVECTOR); + c_total = 0; + + do + { + int c_chr; + + if (c_total + 1 > c_len) + { + /* Grow the bytevector. */ + c_bv = (char *) scm_gc_realloc (c_bv, c_len, c_len * 2, + SCM_GC_BYTEVECTOR); + c_len *= 2; + } + + /* We can't use `scm_c_read ()' since it blocks. */ + c_chr = scm_getc (port); + if (c_chr != EOF) + { + c_bv[c_total] = (char) c_chr; + c_total++; + } + } + while ((scm_is_true (scm_char_ready_p (port))) + && (!SCM_EOF_OBJECT_P (scm_peek_char (port)))); + + if (c_total == 0) + { + result = SCM_EOF_VAL; + scm_gc_free (c_bv, c_len, SCM_GC_BYTEVECTOR); + } + else + { + if (c_len > c_total) + { + /* Shrink the bytevector. */ + c_bv = (char *) scm_gc_realloc (c_bv, c_len, c_total, + SCM_GC_BYTEVECTOR); + c_len = (unsigned) c_total; + } + + result = scm_c_take_bytevector ((signed char *) c_bv, c_len); + } + + return result; +} +#undef FUNC_NAME + +SCM_DEFINE (scm_get_bytevector_all, "get-bytevector-all", 1, 0, 0, + (SCM port), + "Read from @var{port}, blocking as necessary, until " + "the end-of-file is reached. Return either " + "a new bytevector containing the data read or the " + "end-of-file object (if no data were available).") +#define FUNC_NAME s_scm_get_bytevector_all +{ + SCM result; + char *c_bv; + unsigned c_len, c_count; + size_t c_read, c_total; + + SCM_VALIDATE_BINARY_INPUT_PORT (1, port); + + c_len = c_count = 4096; + c_bv = (char *) scm_gc_malloc (c_len, SCM_GC_BYTEVECTOR); + c_total = c_read = 0; + + do + { + if (c_total + c_read > c_len) + { + /* Grow the bytevector. */ + c_bv = (char *) scm_gc_realloc (c_bv, c_len, c_len * 2, + SCM_GC_BYTEVECTOR); + c_count = c_len; + c_len *= 2; + } + + /* `scm_c_read ()' blocks until C_COUNT bytes are available or EOF is + reached. */ + c_read = scm_c_read (port, c_bv + c_total, c_count); + c_total += c_read, c_count -= c_read; + } + while (!SCM_EOF_OBJECT_P (scm_peek_char (port))); + + if (c_total == 0) + { + result = SCM_EOF_VAL; + scm_gc_free (c_bv, c_len, SCM_GC_BYTEVECTOR); + } + else + { + if (c_len > c_total) + { + /* Shrink the bytevector. */ + c_bv = (char *) scm_gc_realloc (c_bv, c_len, c_total, + SCM_GC_BYTEVECTOR); + c_len = (unsigned) c_total; + } + + result = scm_c_take_bytevector ((signed char *) c_bv, c_len); + } + + return result; +} +#undef FUNC_NAME + + + +/* Binary output. */ + +/* We currently don't support specific binary input ports. */ +#define SCM_VALIDATE_BINARY_OUTPUT_PORT SCM_VALIDATE_OPOUTPORT + + +SCM_DEFINE (scm_put_u8, "put-u8", 2, 0, 0, + (SCM port, SCM octet), + "Write @var{octet} to binary port @var{port}.") +#define FUNC_NAME s_scm_put_u8 +{ + scm_t_uint8 c_octet; + + SCM_VALIDATE_BINARY_OUTPUT_PORT (1, port); + c_octet = scm_to_uint8 (octet); + + scm_putc ((char) c_octet, port); + + return SCM_UNSPECIFIED; +} +#undef FUNC_NAME + +SCM_DEFINE (scm_put_bytevector, "put-bytevector", 2, 2, 0, + (SCM port, SCM bv, SCM start, SCM count), + "Write the contents of @var{bv} to @var{port}, optionally " + "starting at index @var{start} and limiting to @var{count} " + "octets.") +#define FUNC_NAME s_scm_put_bytevector +{ + char *c_bv; + unsigned c_start, c_count, c_len; + + SCM_VALIDATE_BINARY_OUTPUT_PORT (1, port); + SCM_VALIDATE_BYTEVECTOR (2, bv); + + c_len = SCM_BYTEVECTOR_LENGTH (bv); + c_bv = (char *) SCM_BYTEVECTOR_CONTENTS (bv); + + if (start != SCM_UNDEFINED) + { + c_start = scm_to_uint (start); + + if (count != SCM_UNDEFINED) + { + c_count = scm_to_uint (count); + if (SCM_UNLIKELY (c_start + c_count > c_len)) + scm_out_of_range (FUNC_NAME, count); + } + else + { + if (SCM_UNLIKELY (c_start >= c_len)) + scm_out_of_range (FUNC_NAME, start); + else + c_count = c_len - c_start; + } + } + else + c_start = 0, c_count = c_len; + + scm_c_write (port, c_bv + c_start, c_count); + + return SCM_UNSPECIFIED; +} +#undef FUNC_NAME + + + +/* Bytevector output port ("bop" for short). */ + +/* Implementation of "bops". + + Each bop has an internal buffer, of type `scm_t_bop_buffer', attached to + it. The procedure returned along with the output port is actually an + applicable SMOB. The SMOB holds a reference to the port. When applied, + the SMOB swallows the port's internal buffer, turning it into a + bytevector, and resets it. + + XXX: Access to a bop's internal buffer is not thread-safe. */ + +static scm_t_bits bytevector_output_port_type = 0; + +SCM_SMOB (bytevector_output_port_procedure, + "r6rs-bytevector-output-port-procedure", + 0); + +#define SCM_GC_BOP "r6rs-bytevector-output-port" +#define SCM_BOP_BUFFER_INITIAL_SIZE 4096 + +/* Representation of a bop's internal buffer. */ +typedef struct +{ + size_t total_len; + size_t len; + size_t pos; + char *buffer; +} scm_t_bop_buffer; + + +/* Accessing a bop's buffer. */ +#define SCM_BOP_BUFFER(_port) \ + ((scm_t_bop_buffer *) SCM_STREAM (_port)) +#define SCM_SET_BOP_BUFFER(_port, _buf) \ + (SCM_SETSTREAM ((_port), (scm_t_bits) (_buf))) + + +static inline void +bop_buffer_init (scm_t_bop_buffer *buf) +{ + buf->total_len = buf->len = buf->pos = 0; + buf->buffer = NULL; +} + +static inline void +bop_buffer_grow (scm_t_bop_buffer *buf, size_t min_size) +{ + char *new_buf; + size_t new_size; + + for (new_size = buf->total_len + ? buf->total_len : SCM_BOP_BUFFER_INITIAL_SIZE; + new_size < min_size; + new_size *= 2); + + if (buf->buffer) + new_buf = scm_gc_realloc ((void *) buf->buffer, buf->total_len, + new_size, SCM_GC_BOP); + else + new_buf = scm_gc_malloc (new_size, SCM_GC_BOP); + + buf->buffer = new_buf; + buf->total_len = new_size; +} + +static inline SCM +make_bop (void) +{ + SCM port, bop_proc; + scm_t_port *c_port; + scm_t_bop_buffer *buf; + const unsigned long mode_bits = SCM_OPN | SCM_WRTNG; + + port = scm_new_port_table_entry (bytevector_output_port_type); + + buf = (scm_t_bop_buffer *) scm_gc_malloc (sizeof (* buf), SCM_GC_BOP); + bop_buffer_init (buf); + + c_port = SCM_PTAB_ENTRY (port); + c_port->write_buf = c_port->write_pos = c_port->write_end = NULL; + c_port->write_buf_size = 0; + + SCM_SET_BOP_BUFFER (port, buf); + + /* Mark PORT as open and writable. */ + SCM_SET_CELL_TYPE (port, bytevector_output_port_type | mode_bits); + + /* Make the bop procedure. */ + SCM_NEWSMOB (bop_proc, bytevector_output_port_procedure, + SCM_PACK (port)); + + return (scm_values (scm_list_2 (port, bop_proc))); +} + +static size_t +bop_free (SCM port) +{ + /* The port itself is necessarily freed _after_ the bop proc, since the bop + proc holds a reference to it. Thus we can safely free the internal + buffer when the bop becomes unreferenced. */ + scm_t_bop_buffer *buf; + + buf = SCM_BOP_BUFFER (port); + if (buf->buffer) + scm_gc_free (buf->buffer, buf->total_len, SCM_GC_BOP); + + scm_gc_free (buf, sizeof (* buf), SCM_GC_BOP); + + return 0; +} + +/* Write SIZE octets from DATA to PORT. */ +static void +bop_write (SCM port, const void *data, size_t size) +{ + scm_t_bop_buffer *buf; + + buf = SCM_BOP_BUFFER (port); + + if (buf->pos + size > buf->total_len) + bop_buffer_grow (buf, buf->pos + size); + + memcpy (buf->buffer + buf->pos, data, size); + buf->pos += size; + buf->len = (buf->len > buf->pos) ? buf->len : buf->pos; +} + +static scm_t_off +bop_seek (SCM port, scm_t_off offset, int whence) +#define FUNC_NAME "bop_seek" +{ + scm_t_bop_buffer *buf; + + buf = SCM_BOP_BUFFER (port); + switch (whence) + { + case SEEK_CUR: + offset += (scm_t_off) buf->pos; + /* Fall through. */ + + case SEEK_SET: + if (offset < 0 || (unsigned) offset > buf->len) + scm_out_of_range (FUNC_NAME, scm_from_int (offset)); + else + buf->pos = offset; + break; + + case SEEK_END: + if (offset < 0 || (unsigned) offset >= buf->len) + scm_out_of_range (FUNC_NAME, scm_from_int (offset)); + else + buf->pos = buf->len - (offset + 1); + break; + + default: + scm_wrong_type_arg_msg (FUNC_NAME, 0, port, + "invalid `seek' parameter"); + } + + return buf->pos; +} +#undef FUNC_NAME + +/* Fetch data from a bop. */ +SCM_SMOB_APPLY (bytevector_output_port_procedure, + bop_proc_apply, 0, 0, 0, (SCM bop_proc)) +{ + SCM port, bv; + scm_t_bop_buffer *buf, result_buf; + + port = SCM_PACK (SCM_SMOB_DATA (bop_proc)); + buf = SCM_BOP_BUFFER (port); + + result_buf = *buf; + bop_buffer_init (buf); + + if (result_buf.len == 0) + bv = scm_c_take_bytevector (NULL, 0); + else + { + if (result_buf.total_len > result_buf.len) + /* Shrink the buffer. */ + result_buf.buffer = scm_gc_realloc ((void *) result_buf.buffer, + result_buf.total_len, + result_buf.len, + SCM_GC_BOP); + + bv = scm_c_take_bytevector ((signed char *) result_buf.buffer, + result_buf.len); + } + + return bv; +} + +SCM_SMOB_MARK (bytevector_output_port_procedure, bop_proc_mark, + bop_proc) +{ + /* Mark the port associated with BOP_PROC. */ + return (SCM_PACK (SCM_SMOB_DATA (bop_proc))); +} + + +SCM_DEFINE (scm_open_bytevector_output_port, + "open-bytevector-output-port", 0, 1, 0, + (SCM transcoder), + "Return two values: an output port and a procedure. The latter " + "should be called with zero arguments to obtain a bytevector " + "containing the data accumulated by the port.") +#define FUNC_NAME s_scm_open_bytevector_output_port +{ + if (!SCM_UNBNDP (transcoder) && !scm_is_false (transcoder)) + transcoders_not_implemented (); + + return (make_bop ()); +} +#undef FUNC_NAME + +static inline void +initialize_bytevector_output_ports (void) +{ + bytevector_output_port_type = + scm_make_port_type ("r6rs-bytevector-output-port", + NULL, bop_write); + + scm_set_port_seek (bytevector_output_port_type, bop_seek); + scm_set_port_free (bytevector_output_port_type, bop_free); +} + + +/* Custom binary output port ("cbop" for short). */ + +static scm_t_bits custom_binary_output_port_type; + +/* Return the various procedures of PORT. */ +#define SCM_CBOP_WRITE_PROC(_port) \ + SCM_SIMPLE_VECTOR_REF (SCM_PACK (SCM_STREAM (_port)), 0) + + +static inline SCM +make_cbop (SCM write_proc, SCM get_position_proc, + SCM set_position_proc, SCM close_proc) +{ + SCM port, method_vector; + scm_t_port *c_port; + const unsigned long mode_bits = SCM_OPN | SCM_WRTNG; + + /* Store the various methods and bytevector in a vector. */ + method_vector = scm_c_make_vector (4, SCM_BOOL_F); + SCM_SIMPLE_VECTOR_SET (method_vector, 0, write_proc); + SCM_SIMPLE_VECTOR_SET (method_vector, 1, get_position_proc); + SCM_SIMPLE_VECTOR_SET (method_vector, 2, set_position_proc); + SCM_SIMPLE_VECTOR_SET (method_vector, 3, close_proc); + + port = scm_new_port_table_entry (custom_binary_output_port_type); + + /* Attach it the method vector. */ + SCM_SETSTREAM (port, SCM_UNPACK (method_vector)); + + /* Have the port directly access the buffer (bytevector). */ + c_port = SCM_PTAB_ENTRY (port); + c_port->write_buf = c_port->write_pos = c_port->write_end = NULL; + c_port->write_buf_size = c_port->read_buf_size = 0; + + /* Mark PORT as open, writable and unbuffered. */ + SCM_SET_CELL_TYPE (port, custom_binary_output_port_type | mode_bits); + + return port; +} + +/* Write SIZE octets from DATA to PORT. */ +static void +cbop_write (SCM port, const void *data, size_t size) +#define FUNC_NAME "cbop_write" +{ + long int c_result; + size_t c_written; + SCM bv, write_proc, result; + + /* XXX: Allocating a new bytevector at each `write' call is inefficient, + but necessary since (1) we don't control the lifetime of the buffer + pointed to by DATA, and (2) the `write!' procedure could capture the + bytevector it is passed. */ + bv = scm_c_make_bytevector (size); + memcpy (SCM_BYTEVECTOR_CONTENTS (bv), data, size); + + write_proc = SCM_CBOP_WRITE_PROC (port); + + /* Since the `write' procedure of Guile's ports has type `void', it must + try hard to write exactly SIZE bytes, regardless of how many bytes the + sink can handle. */ + for (c_written = 0; + c_written < size; + c_written += c_result) + { + result = scm_call_3 (write_proc, bv, + scm_from_size_t (c_written), + scm_from_size_t (size - c_written)); + + c_result = scm_to_long (result); + if (SCM_UNLIKELY (c_result < 0 + || (size_t) c_result > (size - c_written))) + scm_wrong_type_arg_msg (FUNC_NAME, 0, result, + "R6RS custom binary output port `write!' " + "returned a incorrect integer"); + } +} +#undef FUNC_NAME + + +SCM_DEFINE (scm_make_custom_binary_output_port, + "make-custom-binary-output-port", 5, 0, 0, + (SCM id, SCM write_proc, SCM get_position_proc, + SCM set_position_proc, SCM close_proc), + "Return a new custom binary output port whose output is drained " + "by invoking @var{write_proc} and passing it a bytevector, an " + "index where octets should be written, and an octet count.") +#define FUNC_NAME s_scm_make_custom_binary_output_port +{ + SCM_VALIDATE_STRING (1, id); + SCM_VALIDATE_PROC (2, write_proc); + + if (!scm_is_false (get_position_proc)) + SCM_VALIDATE_PROC (3, get_position_proc); + + if (!scm_is_false (set_position_proc)) + SCM_VALIDATE_PROC (4, set_position_proc); + + if (!scm_is_false (close_proc)) + SCM_VALIDATE_PROC (5, close_proc); + + return (make_cbop (write_proc, get_position_proc, set_position_proc, + close_proc)); +} +#undef FUNC_NAME + + +/* Instantiate the custom binary output port type. */ +static inline void +initialize_custom_binary_output_ports (void) +{ + custom_binary_output_port_type = + scm_make_port_type ("r6rs-custom-binary-output-port", + NULL, cbop_write); + + scm_set_port_mark (custom_binary_output_port_type, cbp_mark); + scm_set_port_seek (custom_binary_output_port_type, cbp_seek); + scm_set_port_close (custom_binary_output_port_type, cbp_close); +} + + +/* Initialization. */ + +void +scm_init_r6rs_ports (void) +{ +#include "libguile/r6rs-ports.x" + + initialize_bytevector_input_ports (); + initialize_custom_binary_input_ports (); + initialize_bytevector_output_ports (); + initialize_custom_binary_output_ports (); +} diff --git a/libguile/r6rs-ports.h b/libguile/r6rs-ports.h new file mode 100644 index 000000000..5e1707a88 --- /dev/null +++ b/libguile/r6rs-ports.h @@ -0,0 +1,44 @@ +#ifndef SCM_R6RS_PORTS_H +#define SCM_R6RS_PORTS_H + +/* Copyright (C) 2009 Free Software Foundation, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + + + +#include "libguile/__scm.h" + +/* R6RS I/O Ports. */ + +SCM_API SCM scm_eof_object (void); +SCM_API SCM scm_open_bytevector_input_port (SCM, SCM); +SCM_API SCM scm_make_custom_binary_input_port (SCM, SCM, SCM, SCM, SCM); +SCM_API SCM scm_get_u8 (SCM); +SCM_API SCM scm_lookahead_u8 (SCM); +SCM_API SCM scm_get_bytevector_n (SCM, SCM); +SCM_API SCM scm_get_bytevector_n_x (SCM, SCM, SCM, SCM); +SCM_API SCM scm_get_bytevector_some (SCM); +SCM_API SCM scm_get_bytevector_all (SCM); +SCM_API SCM scm_put_u8 (SCM, SCM); +SCM_API SCM scm_put_bytevector (SCM, SCM, SCM, SCM); +SCM_API SCM scm_open_bytevector_output_port (SCM); +SCM_API SCM scm_make_custom_binary_output_port (SCM, SCM, SCM, SCM, SCM); + +SCM_API void scm_init_r6rs_ports (void); + +#endif /* SCM_R6RS_PORTS_H */ diff --git a/libguile/ramap.c b/libguile/ramap.c index 1bc4fdd38..e141c18b7 100644 --- a/libguile/ramap.c +++ b/libguile/ramap.c @@ -1,18 +1,19 @@ /* Copyright (C) 1996,1998,2000,2001,2004,2005, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/ramap.h b/libguile/ramap.h index 9d870389a..d6cb19166 100644 --- a/libguile/ramap.h +++ b/libguile/ramap.h @@ -6,18 +6,19 @@ /* Copyright (C) 1995,1996,1997,2000, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/random.c b/libguile/random.c index f5f706f85..9f11dabe8 100644 --- a/libguile/random.c +++ b/libguile/random.c @@ -1,17 +1,18 @@ /* Copyright (C) 1999,2000,2001, 2003, 2005, 2006 Free Software Foundation, Inc. * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/random.h b/libguile/random.h index ae44092ab..6cf404f8d 100644 --- a/libguile/random.h +++ b/libguile/random.h @@ -6,18 +6,19 @@ /* Copyright (C) 1999,2000,2001, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/rdelim.c b/libguile/rdelim.c index c9cc0164d..04a0944f4 100644 --- a/libguile/rdelim.c +++ b/libguile/rdelim.c @@ -1,18 +1,19 @@ /* Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2006 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ #ifdef HAVE_CONFIG_H diff --git a/libguile/rdelim.h b/libguile/rdelim.h index 17efb4fe5..2e401e4fe 100644 --- a/libguile/rdelim.h +++ b/libguile/rdelim.h @@ -6,18 +6,19 @@ /* Copyright (C) 1995,1996,1997,1998,2000,2001, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/read.c b/libguile/read.c index 47b80041e..8efac67af 100644 --- a/libguile/read.c +++ b/libguile/read.c @@ -1,19 +1,20 @@ -/* Copyright (C) 1995,1996,1997,1999,2000,2001,2003, 2004, 2006, 2007, 2008 Free Software +/* Copyright (C) 1995,1996,1997,1999,2000,2001,2003, 2004, 2006, 2007, 2008, 2009 Free Software * Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ @@ -28,6 +29,7 @@ #include #include "libguile/_scm.h" +#include "libguile/bytevectors.h" #include "libguile/chars.h" #include "libguile/eval.h" #include "libguile/unif.h" @@ -177,11 +179,12 @@ static SCM *scm_read_hash_procedures; /* An inlinable version of `scm_c_downcase ()'. */ #define CHAR_DOWNCASE(_chr) \ - (((_chr) <= UCHAR_MAX) ? tolower (_chr) : (_chr)) + (((_chr) <= UCHAR_MAX) ? tolower ((int) (_chr)) : (_chr)) /* Read an SCSH block comment. */ static inline SCM scm_read_scsh_block_comment (int chr, SCM port); +static SCM scm_read_commented_expression (int chr, SCM port); /* Read from PORT until a delimiter (e.g., a whitespace) is read. Return zero if the whole token fits in BUF, non-zero otherwise. */ @@ -257,6 +260,9 @@ flush_ws (SCM port, const char *eoferr) case '!': scm_read_scsh_block_comment (c, port); break; + case ';': + scm_read_commented_expression (c, port); + break; default: scm_ungetc (c, port); return '#'; @@ -381,110 +387,167 @@ scm_read_string (int chr, SCM port) object (the string returned). */ SCM str = SCM_BOOL_F; - char c_str[READER_STRING_BUFFER_SIZE]; unsigned c_str_len = 0; - int c; + scm_t_wchar c; + str = scm_i_make_string (READER_STRING_BUFFER_SIZE, NULL); while ('"' != (c = scm_getc (port))) { if (c == EOF) - str_eof: scm_i_input_error (FUNC_NAME, port, - "end of file in string constant", - SCM_EOL); + { + str_eof: + scm_i_input_error (FUNC_NAME, port, + "end of file in string constant", SCM_EOL); + } - if (c_str_len + 1 >= sizeof (c_str)) - { - /* Flush the C buffer onto a Scheme string. */ - SCM addy; + if (c_str_len + 1 >= scm_i_string_length (str)) + { + SCM addy = scm_i_make_string (READER_STRING_BUFFER_SIZE, NULL); - if (str == SCM_BOOL_F) - str = scm_c_make_string (0, SCM_MAKE_CHAR ('X')); - - addy = scm_from_locale_stringn (c_str, c_str_len); - str = scm_string_append_shared (scm_list_2 (str, addy)); - - c_str_len = 0; - } + str = scm_string_append (scm_list_2 (str, addy)); + } if (c == '\\') - switch (c = scm_getc (port)) - { - case EOF: - goto str_eof; - case '"': - case '\\': - break; + { + switch (c = scm_getc (port)) + { + case EOF: + goto str_eof; + case '"': + case '\\': + break; #if SCM_ENABLE_ELISP - case '(': - case ')': - if (SCM_ESCAPED_PARENS_P) - break; - goto bad_escaped; + case '(': + case ')': + if (SCM_ESCAPED_PARENS_P) + break; + goto bad_escaped; #endif - case '\n': - continue; - case '0': - c = '\0'; - break; - case 'f': - c = '\f'; - break; - case 'n': - c = '\n'; - break; - case 'r': - c = '\r'; - break; - case 't': - c = '\t'; - break; - case 'a': - c = '\007'; - break; - case 'v': - c = '\v'; - break; - case 'x': - { - int a, b; - a = scm_getc (port); - if (a == EOF) goto str_eof; - b = scm_getc (port); - if (b == EOF) goto str_eof; - if ('0' <= a && a <= '9') a -= '0'; - else if ('A' <= a && a <= 'F') a = a - 'A' + 10; - else if ('a' <= a && a <= 'f') a = a - 'a' + 10; - else goto bad_escaped; - if ('0' <= b && b <= '9') b -= '0'; - else if ('A' <= b && b <= 'F') b = b - 'A' + 10; - else if ('a' <= b && b <= 'f') b = b - 'a' + 10; - else goto bad_escaped; - c = a * 16 + b; - break; - } - default: - bad_escaped: - scm_i_input_error (FUNC_NAME, port, - "illegal character in escape sequence: ~S", - scm_list_1 (SCM_MAKE_CHAR (c))); - } - c_str[c_str_len++] = c; + case '\n': + continue; + case '0': + c = '\0'; + break; + case 'f': + c = '\f'; + break; + case 'n': + c = '\n'; + break; + case 'r': + c = '\r'; + break; + case 't': + c = '\t'; + break; + case 'a': + c = '\007'; + break; + case 'v': + c = '\v'; + break; + case 'x': + { + scm_t_wchar a, b; + a = scm_getc (port); + if (a == EOF) + goto str_eof; + b = scm_getc (port); + if (b == EOF) + goto str_eof; + if ('0' <= a && a <= '9') + a -= '0'; + else if ('A' <= a && a <= 'F') + a = a - 'A' + 10; + else if ('a' <= a && a <= 'f') + a = a - 'a' + 10; + else + { + c = a; + goto bad_escaped; + } + if ('0' <= b && b <= '9') + b -= '0'; + else if ('A' <= b && b <= 'F') + b = b - 'A' + 10; + else if ('a' <= b && b <= 'f') + b = b - 'a' + 10; + else + { + c = b; + goto bad_escaped; + } + c = a * 16 + b; + break; + } + case 'u': + { + scm_t_wchar a; + int i; + c = 0; + for (i = 0; i < 4; i++) + { + a = scm_getc (port); + if (a == EOF) + goto str_eof; + if ('0' <= a && a <= '9') + a -= '0'; + else if ('A' <= a && a <= 'F') + a = a - 'A' + 10; + else if ('a' <= a && a <= 'f') + a = a - 'a' + 10; + else + { + c = a; + goto bad_escaped; + } + c = c * 16 + a; + } + break; + } + case 'U': + { + scm_t_wchar a; + int i; + c = 0; + for (i = 0; i < 6; i++) + { + a = scm_getc (port); + if (a == EOF) + goto str_eof; + if ('0' <= a && a <= '9') + a -= '0'; + else if ('A' <= a && a <= 'F') + a = a - 'A' + 10; + else if ('a' <= a && a <= 'f') + a = a - 'a' + 10; + else + { + c = a; + goto bad_escaped; + } + c = c * 16 + a; + } + break; + } + default: + bad_escaped: + scm_i_input_error (FUNC_NAME, port, + "illegal character in escape sequence: ~S", + scm_list_1 (SCM_MAKE_CHAR (c))); + } + } + str = scm_i_string_start_writing (str); + scm_i_string_set_x (str, c_str_len++, c); + scm_i_string_stop_writing (); } if (c_str_len > 0) { - SCM addy; - - addy = scm_from_locale_stringn (c_str, c_str_len); - if (str == SCM_BOOL_F) - str = addy; - else - str = scm_string_append_shared (scm_list_2 (str, addy)); + return scm_i_substring_copy (str, 0, c_str_len); } - else - str = (str == SCM_BOOL_F) ? scm_nullstr : str; - - return str; + + return scm_nullstr; } #undef FUNC_NAME @@ -552,12 +615,21 @@ scm_read_mixed_case_symbol (int chr, SCM port) if (scm_is_pair (str)) { + size_t len; + str = scm_string_concatenate (scm_reverse_x (str, SCM_EOL)); - result = scm_string_to_symbol (str); + len = scm_c_string_length (str); /* Per SRFI-88, `:' alone is an identifier, not a keyword. */ - if (postfix && ends_with_colon && (scm_c_string_length (result) > 1)) - result = scm_symbol_to_keyword (result); + if (postfix && ends_with_colon && (len > 1)) + { + /* Strip off colon. */ + str = scm_c_substring (str, 0, len-1); + result = scm_string_to_symbol (str); + result = scm_symbol_to_keyword (result); + } + else + result = scm_string_to_symbol (str); } else { @@ -691,6 +763,65 @@ scm_read_quote (int chr, SCM port) return p; } +SCM_SYMBOL (sym_syntax, "syntax"); +SCM_SYMBOL (sym_quasisyntax, "quasisyntax"); +SCM_SYMBOL (sym_unsyntax, "unsyntax"); +SCM_SYMBOL (sym_unsyntax_splicing, "unsyntax-splicing"); + +static SCM +scm_read_syntax (int chr, SCM port) +{ + SCM p; + long line = SCM_LINUM (port); + int column = SCM_COL (port) - 1; + + switch (chr) + { + case '`': + p = sym_quasisyntax; + break; + + case '\'': + p = sym_syntax; + break; + + case ',': + { + int c; + + c = scm_getc (port); + if ('@' == c) + p = sym_unsyntax_splicing; + else + { + scm_ungetc (c, port); + p = sym_unsyntax; + } + break; + } + + default: + fprintf (stderr, "%s: unhandled syntax character (%i)\n", + "scm_read_syntax", chr); + abort (); + } + + p = scm_cons2 (p, scm_read_expression (port), SCM_EOL); + if (SCM_RECORD_POSITIONS_P) + scm_whash_insert (scm_source_whash, p, + scm_make_srcprops (line, column, + SCM_FILENAME (port), + SCM_COPY_SOURCE_P + ? (scm_cons2 (SCM_CAR (p), + SCM_CAR (SCM_CDR (p)), + SCM_EOL)) + : SCM_UNDEFINED, + SCM_EOL)); + + + return p; +} + static inline SCM scm_read_semicolon_comment (int chr, SCM port) { @@ -727,7 +858,7 @@ static SCM scm_read_character (int chr, SCM port) #define FUNC_NAME "scm_lreadr" { - unsigned c; + SCM ch; char charname[READER_CHAR_NAME_MAX_SIZE]; size_t charname_len; @@ -760,10 +891,9 @@ scm_read_character (int chr, SCM port) return SCM_MAKE_CHAR (SCM_I_INUM (p)); } - for (c = 0; c < scm_n_charnames; c++) - if (scm_charnames[c] - && (!strncasecmp (scm_charnames[c], charname, charname_len))) - return SCM_MAKE_CHAR (scm_charnums[c]); + ch = scm_i_charname_to_char (charname, charname_len); + if (scm_is_true (ch)) + return ch; char_error: scm_i_input_error (FUNC_NAME, port, "unknown character name ~a", @@ -809,6 +939,30 @@ scm_read_srfi4_vector (int chr, SCM port) return scm_i_read_array (port, chr); } +static SCM +scm_read_bytevector (int chr, SCM port) +{ + chr = scm_getc (port); + if (chr != 'u') + goto syntax; + + chr = scm_getc (port); + if (chr != '8') + goto syntax; + + chr = scm_getc (port); + if (chr != '(') + goto syntax; + + return scm_u8_list_to_bytevector (scm_read_sexp (chr, port)); + + syntax: + scm_i_input_error ("read_bytevector", port, + "invalid bytevector prefix", + SCM_MAKE_CHAR (chr)); + return SCM_UNSPECIFIED; +} + static SCM scm_read_guile_bit_vector (int chr, SCM port) { @@ -853,6 +1007,20 @@ scm_read_scsh_block_comment (int chr, SCM port) return SCM_UNSPECIFIED; } +static SCM +scm_read_commented_expression (int chr, SCM port) +{ + int c; + + c = flush_ws (port, (char *) NULL); + if (EOF == c) + scm_i_input_error ("read_commented_expression", port, + "no expression after #; comment", SCM_EOL); + scm_ungetc (c, port); + scm_read_expression (port); + return SCM_UNSPECIFIED; +} + static SCM scm_read_extended_symbol (int chr, SCM port) { @@ -963,6 +1131,8 @@ scm_read_sharp (int chr, SCM port) case 'f': /* This one may return either a boolean or an SRFI-4 vector. */ return (scm_read_srfi4_vector (chr, port)); + case 'v': + return (scm_read_bytevector (chr, port)); case '*': return (scm_read_guile_bit_vector (chr, port)); case 't': @@ -1014,6 +1184,12 @@ scm_read_sharp (int chr, SCM port) return (scm_read_extended_symbol (chr, port)); case '!': return (scm_read_scsh_block_comment (chr, port)); + case ';': + return (scm_read_commented_expression (chr, port)); + case '`': + case '\'': + case ',': + return (scm_read_syntax (chr, port)); default: result = scm_read_sharp_extension (chr, port); if (scm_is_eq (result, SCM_UNSPECIFIED)) diff --git a/libguile/read.h b/libguile/read.h index 4253622da..20d3f4bf7 100644 --- a/libguile/read.h +++ b/libguile/read.h @@ -6,18 +6,19 @@ /* Copyright (C) 1995,1996,2000, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/regex-posix.c b/libguile/regex-posix.c index 187261421..6259f28ae 100644 --- a/libguile/regex-posix.c +++ b/libguile/regex-posix.c @@ -1,18 +1,19 @@ /* Copyright (C) 1997, 1998, 1999, 2000, 2001, 2004, 2006, 2007 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/regex-posix.h b/libguile/regex-posix.h index 2863b0562..8060fe3b7 100644 --- a/libguile/regex-posix.h +++ b/libguile/regex-posix.h @@ -6,18 +6,19 @@ /* Copyright (C) 1997,1998,2000,2001, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/root.c b/libguile/root.c index 0d4ab29e5..83960b5d8 100644 --- a/libguile/root.c +++ b/libguile/root.c @@ -1,18 +1,19 @@ /* Copyright (C) 1995,1996,1997,1998,1999,2000, 2001, 2002, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/root.h b/libguile/root.h index a8116c879..676a7b44c 100644 --- a/libguile/root.h +++ b/libguile/root.h @@ -6,18 +6,19 @@ /* Copyright (C) 1996,1998,2000,2001, 2002, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/rw.c b/libguile/rw.c index 3e814740a..a9b4a329a 100644 --- a/libguile/rw.c +++ b/libguile/rw.c @@ -1,18 +1,19 @@ -/* Copyright (C) 2001, 2006 Free Software Foundation, Inc. +/* Copyright (C) 2001, 2006, 2009 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ @@ -130,6 +131,7 @@ SCM_DEFINE (scm_read_string_x_partial, "read-string!/partial", 1, 3, 0, don't touch the file descriptor. otherwise the "return immediately if something is available" rule may be violated. */ + str = scm_i_string_start_writing (str); dest = scm_i_string_writable_chars (str) + offset; chars_read = scm_take_from_input_buffers (port, dest, read_len); scm_i_string_stop_writing (); @@ -139,6 +141,7 @@ SCM_DEFINE (scm_read_string_x_partial, "read-string!/partial", 1, 3, 0, if (chars_read == 0 && read_len > 0) /* don't confuse read_len == 0 with EOF. */ { + str = scm_i_string_start_writing (str); dest = scm_i_string_writable_chars (str) + offset; SCM_SYSCALL (chars_read = read (fdes, dest, read_len)); scm_i_string_stop_writing (); @@ -206,7 +209,7 @@ SCM_DEFINE (scm_write_string_partial, "write-string/partial", 1, 3, 0, #define FUNC_NAME s_scm_write_string_partial { const char *src; - long write_len; + scm_t_off write_len; int fdes; { @@ -231,7 +234,7 @@ SCM_DEFINE (scm_write_string_partial, "write-string/partial", 1, 3, 0, SCM port = (SCM_UNBNDP (port_or_fdes)? scm_current_output_port () : port_or_fdes); scm_t_port *pt; - off_t space; + scm_t_off space; SCM_VALIDATE_OPFPORT (2, port); SCM_VALIDATE_OUTPUT_PORT (2, port); diff --git a/libguile/rw.h b/libguile/rw.h index b526051fc..d54f1b3ef 100644 --- a/libguile/rw.h +++ b/libguile/rw.h @@ -6,18 +6,19 @@ /* Copyright (C) 2001, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/scmconfig.h.top b/libguile/scmconfig.h.top index dfc7ba99c..b84660b6c 100644 --- a/libguile/scmconfig.h.top +++ b/libguile/scmconfig.h.top @@ -1,16 +1,17 @@ /* Copyright (C) 2003, 2006 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/scmsigs.c b/libguile/scmsigs.c index eb7cec67b..f4772b7a2 100644 --- a/libguile/scmsigs.c +++ b/libguile/scmsigs.c @@ -1,18 +1,19 @@ /* Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2002, 2004, 2006, 2007, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ @@ -305,10 +306,8 @@ SCM_DEFINE (scm_sigaction_for_thread, "sigaction", 1, 3, 0, "a scheme procedure has been specified, that procedure will run\n" "in the given @var{thread}. When no thread has been given, the\n" "thread that made this call to @code{sigaction} is used.\n" - "Flags can " - "optionally be specified for the new handler (@code{SA_RESTART} will\n" - "always be added if it's available and the system is using restartable\n" - "system calls.) The return value is a pair with information about the\n" + "Flags can optionally be specified for the new handler.\n" + "The return value is a pair with information about the\n" "old handler as described above.\n\n" "This interface does not provide access to the \"signal blocking\"\n" "facility. Maybe this is not needed, since the thread support may\n" @@ -332,14 +331,7 @@ SCM_DEFINE (scm_sigaction_for_thread, "sigaction", 1, 3, 0, csig = scm_to_signed_integer (signum, 0, NSIG-1); #if defined(HAVE_SIGACTION) -#if defined(SA_RESTART) && defined(HAVE_RESTARTABLE_SYSCALLS) - /* don't allow SA_RESTART to be omitted if HAVE_RESTARTABLE_SYSCALLS - is defined, since libguile would be likely to produce spurious - EINTR errors. */ - action.sa_flags = SA_RESTART; -#else action.sa_flags = 0; -#endif if (!SCM_UNBNDP (flags)) action.sa_flags |= scm_to_int (flags); sigemptyset (&action.sa_mask); @@ -712,29 +704,6 @@ scm_init_scmsigs () #else orig_handlers[i] = SIG_ERR; #endif - -#ifdef HAVE_RESTARTABLE_SYSCALLS - /* If HAVE_RESTARTABLE_SYSCALLS is defined, it's important that - signals really are restartable. don't rely on the same - run-time that configure got: reset the default for every signal. - */ -#ifdef HAVE_SIGINTERRUPT - siginterrupt (i, 0); -#elif defined(SA_RESTART) - { - struct sigaction action; - - sigaction (i, NULL, &action); - if (!(action.sa_flags & SA_RESTART)) - { - action.sa_flags |= SA_RESTART; - sigaction (i, &action, NULL); - } - } -#endif - /* if neither siginterrupt nor SA_RESTART are available we may - as well assume that signals are always restartable. */ -#endif } scm_c_define ("NSIG", scm_from_long (NSIG)); diff --git a/libguile/scmsigs.h b/libguile/scmsigs.h index bcbf825d4..fce372849 100644 --- a/libguile/scmsigs.h +++ b/libguile/scmsigs.h @@ -6,18 +6,19 @@ /* Copyright (C) 1995,1996,1997,1998,2000, 2002, 2006, 2007, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/script.c b/libguile/script.c index 14691c738..8c4e8ef55 100644 --- a/libguile/script.c +++ b/libguile/script.c @@ -1,17 +1,18 @@ /* Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ /* "script.c" argv tricks for `#!' scripts. @@ -29,6 +30,7 @@ #include "libguile/eval.h" #include "libguile/feature.h" #include "libguile/load.h" +#include "libguile/private-gc.h" /* scm_getenv_int */ #include "libguile/read.h" #include "libguile/script.h" #include "libguile/strings.h" @@ -376,6 +378,10 @@ scm_shell_usage (int fatal, char *message) " --no-debug start with normal evaluator\n" " Default is to enable debugging for interactive\n" " use, but not for `-s' and `-c'.\n" + " --autocompile compile source files automatically\n" + " --no-autocompile disable automatic source file compilation\n" + " Default is to enable autocompilation of source\n" + " files.\n" " -q inhibit loading of user init file\n" " --emacs enable Emacs protocol (experimental)\n" " --use-srfi=LS load SRFI modules for the SRFIs in LS,\n" @@ -404,6 +410,7 @@ SCM_SYMBOL (sym_quit, "quit"); SCM_SYMBOL (sym_use_srfis, "use-srfis"); SCM_SYMBOL (sym_load_path, "%load-path"); SCM_SYMBOL (sym_set_x, "set!"); +SCM_SYMBOL (sym_sys_load_should_autocompile, "%load-should-autocompile"); SCM_SYMBOL (sym_cons, "cons"); SCM_SYMBOL (sym_at, "@"); SCM_SYMBOL (sym_atat, "@@"); @@ -448,6 +455,8 @@ scm_compile_shell_switches (int argc, char **argv) int use_emacs_interface = 0; int turn_on_debugging = 0; int dont_turn_on_debugging = 0; + int turn_on_autocompile = 0; + int dont_turn_on_autocompile = 0; int i; char *argv0 = guile; @@ -584,6 +593,18 @@ scm_compile_shell_switches (int argc, char **argv) turn_on_debugging = 0; } + else if (! strcmp (argv[i], "--autocompile")) + { + turn_on_autocompile = 1; + dont_turn_on_autocompile = 0; + } + + else if (! strcmp (argv[i], "--no-autocompile")) + { + dont_turn_on_autocompile = 1; + turn_on_autocompile = 0; + } + else if (! strcmp (argv[i], "--emacs")) /* use emacs protocol */ use_emacs_interface = 1; @@ -701,6 +722,16 @@ scm_compile_shell_switches (int argc, char **argv) tail = scm_cons (scm_cons (sym_load_user_init, SCM_EOL), tail); } + /* If GUILE_AUTO_COMPILE is not set and no args are given, default to + autocompilation. */ + if (turn_on_autocompile || (scm_getenv_int ("GUILE_AUTO_COMPILE", 1) + && !dont_turn_on_autocompile)) + { + tail = scm_cons (scm_list_3 (sym_set_x, sym_sys_load_should_autocompile, + SCM_BOOL_T), + tail); + } + /* If debugging was requested, or we are interactive and debugging was not explicitly turned off, turn on debugging. */ if (turn_on_debugging || (interactive && !dont_turn_on_debugging)) diff --git a/libguile/script.h b/libguile/script.h index 6c02f8d8d..7e3828aa3 100644 --- a/libguile/script.h +++ b/libguile/script.h @@ -6,18 +6,19 @@ /* Copyright (C) 1997,1998,2000, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/simpos.c b/libguile/simpos.c index e4c27b7e7..41af23378 100644 --- a/libguile/simpos.c +++ b/libguile/simpos.c @@ -2,18 +2,19 @@ * Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/simpos.h b/libguile/simpos.h index 6df8bb1d2..b391a28d8 100644 --- a/libguile/simpos.h +++ b/libguile/simpos.h @@ -6,18 +6,19 @@ /* Copyright (C) 1995,1996,1997,1998,2000, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/smob.c b/libguile/smob.c index ad33933c3..0598bae33 100644 --- a/libguile/smob.c +++ b/libguile/smob.c @@ -1,18 +1,19 @@ /* Copyright (C) 1995,1996,1998,1999,2000,2001, 2003, 2004, 2006, 2009 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/smob.h b/libguile/smob.h index 6f5033605..d435bacb8 100644 --- a/libguile/smob.h +++ b/libguile/smob.h @@ -6,18 +6,19 @@ /* Copyright (C) 1995,1996,1998,1999,2000,2001, 2004, 2006, 2009 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/snarf.h b/libguile/snarf.h index 5c2f18774..03a3edd47 100644 --- a/libguile/snarf.h +++ b/libguile/snarf.h @@ -6,18 +6,19 @@ /* Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2002, 2003, 2004, 2006 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/socket.c b/libguile/socket.c index f34b6d49d..2e02e9082 100644 --- a/libguile/socket.c +++ b/libguile/socket.c @@ -1,18 +1,19 @@ /* Copyright (C) 1996,1997,1998,2000,2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ @@ -1437,6 +1438,7 @@ SCM_DEFINE (scm_recv, "recv!", 2, 1, 0, fd = SCM_FPORT_FDES (sock); len = scm_i_string_length (buf); + buf = scm_i_string_start_writing (buf); dest = scm_i_string_writable_chars (buf); SCM_SYSCALL (rv = recv (fd, dest, len, flg)); scm_i_string_stop_writing (); @@ -1481,6 +1483,7 @@ SCM_DEFINE (scm_send, "send", 2, 1, 0, fd = SCM_FPORT_FDES (sock); len = scm_i_string_length (message); + message = scm_i_string_start_writing (message); src = scm_i_string_writable_chars (message); SCM_SYSCALL (rv = send (fd, src, len, flg)); scm_i_string_stop_writing (); @@ -1549,6 +1552,7 @@ SCM_DEFINE (scm_recvfrom, "recvfrom!", 2, 3, 0, /* recvfrom will not necessarily return an address. usually nothing is returned for stream sockets. */ + str = scm_i_string_start_writing (str); buf = scm_i_string_writable_chars (str); ((struct sockaddr *) &addr)->sa_family = AF_UNSPEC; SCM_SYSCALL (rv = recvfrom (fd, buf + offset, diff --git a/libguile/socket.h b/libguile/socket.h index 133dbf7c6..fcddd780d 100644 --- a/libguile/socket.h +++ b/libguile/socket.h @@ -6,18 +6,19 @@ /* Copyright (C) 1995,1996,1997,2000,2001, 2004, 2005, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/sort.c b/libguile/sort.c index 2a7317663..644526eac 100644 --- a/libguile/sort.c +++ b/libguile/sort.c @@ -1,17 +1,18 @@ /* Copyright (C) 1999,2000,2001,2002, 2004, 2006, 2007, 2008 Free Software Foundation, Inc. * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/sort.h b/libguile/sort.h index 51f292a5c..3ae86c2f3 100644 --- a/libguile/sort.h +++ b/libguile/sort.h @@ -6,18 +6,19 @@ /* Copyright (C) 1999,2000, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/srcprop.c b/libguile/srcprop.c index ee15f641d..2cbf04894 100644 --- a/libguile/srcprop.c +++ b/libguile/srcprop.c @@ -1,18 +1,19 @@ /* Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002, 2006, 2008 Free Software Foundation * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/srcprop.h b/libguile/srcprop.h index a467aa34e..2a27e0409 100644 --- a/libguile/srcprop.h +++ b/libguile/srcprop.h @@ -6,18 +6,19 @@ /* Copyright (C) 1995,1996,2000,2001, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/srfi-13.c b/libguile/srfi-13.c index c8ca78027..781fe6893 100644 --- a/libguile/srfi-13.c +++ b/libguile/srfi-13.c @@ -3,18 +3,19 @@ * Copyright (C) 2001, 2004, 2005, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ @@ -548,6 +549,7 @@ SCM_DEFINE (scm_string_copy_x, "string-copy!", 3, 2, 0, len = cend - cstart; SCM_ASSERT_RANGE (3, s, len <= scm_i_string_length (target) - ctstart); + target = scm_i_string_start_writing (target); ctarget = scm_i_string_writable_chars (target); memmove (ctarget + ctstart, cstr + cstart, len); scm_i_string_stop_writing (); @@ -984,6 +986,7 @@ SCM_DEFINE (scm_substring_fill_x, "string-fill!", 2, 2, 0, 4, end, cend); SCM_VALIDATE_CHAR_COPY (2, chr, c); + str = scm_i_string_start_writing (str); cstr = scm_i_string_writable_chars (str); for (k = cstart; k < cend; k++) cstr[k] = c; @@ -2375,6 +2378,7 @@ string_upcase_x (SCM v, size_t start, size_t end) size_t k; char *dst; + v = scm_i_string_start_writing (v); dst = scm_i_string_writable_chars (v); for (k = start; k < end; ++k) dst[k] = scm_c_upcase (dst[k]); @@ -2441,6 +2445,7 @@ string_downcase_x (SCM v, size_t start, size_t end) size_t k; char *dst; + v = scm_i_string_start_writing (v); dst = scm_i_string_writable_chars (v); for (k = start; k < end; ++k) dst[k] = scm_c_downcase (dst[k]); @@ -2510,6 +2515,7 @@ string_titlecase_x (SCM str, size_t start, size_t end) size_t i; int in_word = 0; + str = scm_i_string_start_writing (str); sz = (unsigned char *) scm_i_string_writable_chars (str); for(i = start; i < end; i++) { @@ -2634,6 +2640,7 @@ SCM_DEFINE (scm_string_reverse, "string-reverse", 1, 2, 0, 2, start, cstart, 3, end, cend); result = scm_string_copy (str); + result = scm_i_string_start_writing (result); ctarget = scm_i_string_writable_chars (result); string_reverse_x (ctarget, cstart, cend); scm_i_string_stop_writing (); @@ -2657,6 +2664,7 @@ SCM_DEFINE (scm_string_reverse_x, "string-reverse!", 1, 2, 0, 2, start, cstart, 3, end, cend); + str = scm_i_string_start_writing (str); cstr = scm_i_string_writable_chars (str); string_reverse_x (cstr, cstart, cend); scm_i_string_stop_writing (); @@ -3017,19 +3025,16 @@ SCM_DEFINE (scm_string_for_each, "string-for-each", 2, 2, 0, "return value is not specified.") #define FUNC_NAME s_scm_string_for_each { - const char *cstr; size_t cstart, cend; scm_t_trampoline_1 proc_tramp = scm_trampoline_1 (proc); SCM_ASSERT (proc_tramp, proc, SCM_ARG1, FUNC_NAME); - MY_VALIDATE_SUBSTRING_SPEC_COPY (2, s, cstr, - 3, start, cstart, - 4, end, cend); + MY_VALIDATE_SUBSTRING_SPEC (2, s, + 3, start, cstart, + 4, end, cend); while (cstart < cend) { - unsigned int c = (unsigned char) cstr[cstart]; - proc_tramp (proc, SCM_MAKE_CHAR (c)); - cstr = scm_i_string_chars (s); + proc_tramp (proc, SCM_MAKE_CHAR (scm_i_string_ref (s, cstart))); cstart++; } @@ -3161,6 +3166,7 @@ SCM_DEFINE (scm_string_xcopy_x, "string-xcopy!", 4, 3, 0, SCM_ASSERT_RANGE (1, tstart, ctstart + (csto - csfrom) <= scm_i_string_length (target)); + target = scm_i_string_start_writing (target); p = scm_i_string_writable_chars (target) + ctstart; cs = scm_i_string_chars (s); while (csfrom < csto) @@ -3199,8 +3205,8 @@ SCM_DEFINE (scm_string_replace, "string-replace", 2, 4, 0, MY_VALIDATE_SUBSTRING_SPEC (2, s2, 5, start2, cstart2, 6, end2, cend2); - result = scm_i_make_string (cstart1 + (cend2 - cstart2) + - scm_i_string_length (s1) - cend1, &p); + result = scm_i_make_string ((cstart1 + cend2 - cstart2 + + scm_i_string_length (s1) - cend1), &p); cstr1 = scm_i_string_chars (s1); cstr2 = scm_i_string_chars (s2); memmove (p, cstr1, cstart1 * sizeof (char)); diff --git a/libguile/srfi-13.h b/libguile/srfi-13.h index f8221ddc6..478a55d64 100644 --- a/libguile/srfi-13.h +++ b/libguile/srfi-13.h @@ -6,18 +6,19 @@ * Copyright (C) 2001, 2004, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/srfi-14.c b/libguile/srfi-14.c index fc047c028..0d614f6d9 100644 --- a/libguile/srfi-14.c +++ b/libguile/srfi-14.c @@ -3,18 +3,19 @@ * Copyright (C) 2001, 2004, 2006, 2007 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ #ifdef HAVE_CONFIG_H diff --git a/libguile/srfi-14.h b/libguile/srfi-14.h index ea8027aac..54e0d329c 100644 --- a/libguile/srfi-14.h +++ b/libguile/srfi-14.h @@ -6,18 +6,19 @@ * Copyright (C) 2001, 2004, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/srfi-4.c b/libguile/srfi-4.c index 3e43a4985..b45d4029b 100644 --- a/libguile/srfi-4.c +++ b/libguile/srfi-4.c @@ -1,20 +1,21 @@ /* srfi-4.c --- Uniform numeric vector datatypes. * - * Copyright (C) 2001, 2004, 2006 Free Software Foundation, Inc. + * Copyright (C) 2001, 2004, 2006, 2009 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ #ifdef HAVE_CONFIG_H @@ -28,6 +29,7 @@ #include "libguile/_scm.h" #include "libguile/__scm.h" #include "libguile/srfi-4.h" +#include "libguile/bytevectors.h" #include "libguile/error.h" #include "libguile/read.h" #include "libguile/ports.h" @@ -580,6 +582,8 @@ scm_i_generalized_vector_type (SCM v) return scm_sym_b; else if (scm_is_uniform_vector (v)) return scm_from_locale_symbol (uvec_tags[SCM_UVEC_TYPE(v)]); + else if (scm_is_bytevector (v)) + return scm_from_locale_symbol ("vu8"); else return SCM_BOOL_F; } @@ -721,6 +725,8 @@ scm_array_handle_uniform_element_size (scm_t_array_handle *h) vec = SCM_I_ARRAY_V (vec); if (scm_is_uniform_vector (vec)) return uvec_sizes[SCM_UVEC_TYPE(vec)]; + if (scm_is_bytevector (vec)) + return 1U; scm_wrong_type_arg_msg (NULL, 0, h->array, "uniform array"); } @@ -761,6 +767,8 @@ scm_array_handle_uniform_writable_elements (scm_t_array_handle *h) char *elts = SCM_UVEC_BASE (vec); return (void *) (elts + size*h->base); } + if (scm_is_bytevector (vec)) + return SCM_BYTEVECTOR_CONTENTS (vec); scm_wrong_type_arg_msg (NULL, 0, h->array, "uniform array"); } diff --git a/libguile/srfi-4.h b/libguile/srfi-4.h index 3c340d91e..a1a9bafc0 100644 --- a/libguile/srfi-4.h +++ b/libguile/srfi-4.h @@ -5,18 +5,19 @@ * Copyright (C) 2001, 2004, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/stackchk.c b/libguile/stackchk.c index a53e67629..b14a71259 100644 --- a/libguile/stackchk.c +++ b/libguile/stackchk.c @@ -1,18 +1,19 @@ /* Copyright (C) 1995,1996,1997, 2000, 2001, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/stackchk.h b/libguile/stackchk.h index 8681f5d46..6aa0fec18 100644 --- a/libguile/stackchk.h +++ b/libguile/stackchk.h @@ -6,18 +6,19 @@ /* Copyright (C) 1995,1996,1998,2000, 2003, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/stacks.c b/libguile/stacks.c index 69fb3406a..45566cafa 100644 --- a/libguile/stacks.c +++ b/libguile/stacks.c @@ -2,18 +2,19 @@ * Copyright (C) 1996,1997,2000,2001, 2006, 2007, 2008, 2009 Free Software Foundation * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/stacks.h b/libguile/stacks.h index 53633bc14..20735eff5 100644 --- a/libguile/stacks.h +++ b/libguile/stacks.h @@ -6,18 +6,19 @@ /* Copyright (C) 1995,1996,2000,2001, 2004, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/stime.c b/libguile/stime.c index 34c8a98fa..a6843377b 100644 --- a/libguile/stime.c +++ b/libguile/stime.c @@ -1,18 +1,19 @@ /* Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ @@ -77,10 +78,6 @@ # include #endif -#if HAVE_CRT_EXTERNS_H -#include /* for Darwin _NSGetEnviron */ -#endif - #ifndef tzname /* For SGI. */ extern char *tzname[]; /* RS6000 and others reject char **tzname. */ #endif @@ -98,15 +95,6 @@ extern char *strptime (); # define timet long #endif -extern char ** environ; - -/* On Apple Darwin in a shared library there's no "environ" to access - directly, instead the address of that variable must be obtained with - _NSGetEnviron(). */ -#if HAVE__NSGETENVIRON && defined (PIC) -#define environ (*_NSGetEnviron()) -#endif - #ifdef HAVE_TIMES static diff --git a/libguile/stime.h b/libguile/stime.h index c64c60ea9..8b70cee62 100644 --- a/libguile/stime.h +++ b/libguile/stime.h @@ -6,18 +6,19 @@ /* Copyright (C) 1995,1996,1997,1998,2000, 2003, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/strerror.c b/libguile/strerror.c index c2f20f0c2..0e0e94ee8 100644 --- a/libguile/strerror.c +++ b/libguile/strerror.c @@ -1,19 +1,20 @@ /* Turning errno values into English error messages. Copyright (C) 1985, 86, 87, 88, 93, 94, 95, 2000, 2001, 2006 Free Software Foundation, Inc. - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License + as published by the Free Software Foundation; either version 3 of + the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA */ char * diff --git a/libguile/strings.c b/libguile/strings.c index 6e3b0a347..8aa1e6622 100644 --- a/libguile/strings.c +++ b/libguile/strings.c @@ -1,18 +1,19 @@ /* Copyright (C) 1995,1996,1998,2000,2001, 2004, 2006, 2008, 2009 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ @@ -23,6 +24,9 @@ #include #include +#include +#include +#include #include "libguile/_scm.h" #include "libguile/chars.h" @@ -41,7 +45,7 @@ * * XXX - keeping an accurate refcount during GC seems to be quite * tricky, so we just keep score of whether a stringbuf might be - * shared, not wether it definitely is. + * shared, not whether it definitely is. * * The scheme I (mvo) tried to keep an accurate reference count would * recount all strings that point to a stringbuf during the mark-phase @@ -58,19 +62,29 @@ * A stringbuf needs to know its length, but only so that it can be * reported when the stringbuf is freed. * - * Stringbufs (and strings) are not stored very compactly: a stringbuf - * has room for about 2*sizeof(scm_t_bits)-1 bytes additional - * information. As a compensation, the code below is made more - * complicated by storing small strings inline in the double cell of a - * stringbuf. So we have fixstrings and bigstrings... + * There are 3 storage strategies for stringbufs: inline, outline, and + * wide. + * + * Inline strings are small 8-bit strings stored within the double + * cell itself. Outline strings are larger 8-bit strings with GC + * allocated storage. Wide strings are 32-bit strings with allocated + * storage. + * + * There was little value in making wide string inlineable, since + * there is only room for three inlined 32-bit characters. Thus wide + * stringbufs are never inlined. */ #define STRINGBUF_F_SHARED 0x100 #define STRINGBUF_F_INLINE 0x200 +#define STRINGBUF_F_WIDE 0x400 /* If true, strings have UCS-4 + encoding. Otherwise, strings + are Latin-1. */ #define STRINGBUF_TAG scm_tc7_stringbuf #define STRINGBUF_SHARED(buf) (SCM_CELL_WORD_0(buf) & STRINGBUF_F_SHARED) #define STRINGBUF_INLINE(buf) (SCM_CELL_WORD_0(buf) & STRINGBUF_F_INLINE) +#define STRINGBUF_WIDE(buf) (SCM_CELL_WORD_0(buf) & STRINGBUF_F_WIDE) #define STRINGBUF_OUTLINE_CHARS(buf) ((char *)SCM_CELL_WORD_1(buf)) #define STRINGBUF_OUTLINE_LENGTH(buf) (SCM_CELL_WORD_2(buf)) @@ -80,6 +94,8 @@ #define STRINGBUF_CHARS(buf) (STRINGBUF_INLINE (buf) \ ? STRINGBUF_INLINE_CHARS (buf) \ : STRINGBUF_OUTLINE_CHARS (buf)) + +#define STRINGBUF_WIDE_CHARS(buf) ((scm_t_wchar *)SCM_CELL_WORD_1(buf)) #define STRINGBUF_LENGTH(buf) (STRINGBUF_INLINE (buf) \ ? STRINGBUF_INLINE_LENGTH (buf) \ : STRINGBUF_OUTLINE_LENGTH (buf)) @@ -89,10 +105,12 @@ #define SET_STRINGBUF_SHARED(buf) \ (SCM_SET_CELL_WORD_0 ((buf), SCM_CELL_WORD_0 (buf) | STRINGBUF_F_SHARED)) -#if SCM_DEBUG +#if SCM_STRING_LENGTH_HISTOGRAM static size_t lenhist[1001]; #endif +/* Make a stringbuf with space for LEN 8-bit Latin-1-encoded + characters. */ static SCM make_stringbuf (size_t len) { @@ -103,7 +121,7 @@ make_stringbuf (size_t len) can be dropped. */ -#if SCM_DEBUG +#if SCM_STRING_LENGTH_HISTOGRAM if (len < 1000) lenhist[len]++; else @@ -124,6 +142,25 @@ make_stringbuf (size_t len) } } +/* Make a stringbuf with space for LEN 32-bit UCS-4-encoded + characters. */ +static SCM +make_wide_stringbuf (size_t len) +{ + scm_t_wchar *mem; +#if SCM_STRING_LENGTH_HISTOGRAM + if (len < 1000) + lenhist[len]++; + else + lenhist[1000]++; +#endif + + mem = scm_gc_malloc (sizeof (scm_t_wchar) * (len + 1), "string"); + mem[len] = 0; + return scm_double_cell (STRINGBUF_TAG | STRINGBUF_F_WIDE, (scm_t_bits) mem, + (scm_t_bits) len, (scm_t_bits) 0); +} + /* Return a new stringbuf whose underlying storage consists of the LEN+1 octets pointed to by STR (the last octet is zero). */ SCM @@ -135,6 +172,49 @@ scm_i_take_stringbufn (char *str, size_t len) (scm_t_bits) len, (scm_t_bits) 0); } +/* Convert a stringbuf containing 8-bit Latin-1-encoded characters to + one containing 32-bit UCS-4-encoded characters. */ +static void +widen_stringbuf (SCM buf) +{ + size_t i, len; + scm_t_wchar *mem; + + if (STRINGBUF_WIDE (buf)) + return; + + if (STRINGBUF_INLINE (buf)) + { + len = STRINGBUF_INLINE_LENGTH (buf); + + mem = scm_gc_malloc (sizeof (scm_t_wchar) * (len + 1), "string"); + for (i = 0; i < len; i++) + mem[i] = + (scm_t_wchar) (unsigned char) STRINGBUF_INLINE_CHARS (buf)[i]; + mem[len] = 0; + + SCM_SET_CELL_WORD_0 (buf, SCM_CELL_WORD_0 (buf) ^ STRINGBUF_F_INLINE); + SCM_SET_CELL_WORD_0 (buf, SCM_CELL_WORD_0 (buf) | STRINGBUF_F_WIDE); + SCM_SET_CELL_WORD_1 (buf, mem); + SCM_SET_CELL_WORD_2 (buf, len); + } + else + { + len = STRINGBUF_OUTLINE_LENGTH (buf); + + mem = scm_gc_malloc (sizeof (scm_t_wchar) * (len + 1), "string"); + for (i = 0; i < len; i++) + mem[i] = + (scm_t_wchar) (unsigned char) STRINGBUF_OUTLINE_CHARS (buf)[i]; + mem[len] = 0; + + scm_gc_free (STRINGBUF_OUTLINE_CHARS (buf), len + 1, "string"); + + SCM_SET_CELL_WORD_0 (buf, SCM_CELL_WORD_0 (buf) | STRINGBUF_F_WIDE); + SCM_SET_CELL_WORD_1 (buf, mem); + SCM_SET_CELL_WORD_2 (buf, len); + } +} scm_i_pthread_mutex_t stringbuf_write_mutex = SCM_I_PTHREAD_MUTEX_INITIALIZER; @@ -168,6 +248,9 @@ scm_i_pthread_mutex_t stringbuf_write_mutex = SCM_I_PTHREAD_MUTEX_INITIALIZER; #define IS_SH_STRING(str) (SCM_CELL_TYPE(str)==SH_STRING_TAG) +/* Create a scheme string with space for LEN 8-bit Latin-1-encoded + characters. CHARSP, if not NULL, will be set to location of the + char array. */ SCM scm_i_make_string (size_t len, char **charsp) { @@ -180,6 +263,21 @@ scm_i_make_string (size_t len, char **charsp) return res; } +/* Create a scheme string with space for LEN 32-bit UCS-4-encoded + characters. CHARSP, if not NULL, will be set to location of the + character array. */ +SCM +scm_i_make_wide_string (size_t len, scm_t_wchar **charsp) +{ + SCM buf = make_wide_stringbuf (len); + SCM res; + if (charsp) + *charsp = STRINGBUF_WIDE_CHARS (buf); + res = scm_double_cell (STRING_TAG, SCM_UNPACK (buf), + (scm_t_bits) 0, (scm_t_bits) len); + return res; +} + static void validate_substring_args (SCM str, size_t start, size_t end) { @@ -238,12 +336,24 @@ scm_i_substring_copy (SCM str, size_t start, size_t end) SCM buf, my_buf; size_t str_start; get_str_buf_start (&str, &buf, &str_start); - my_buf = make_stringbuf (len); - memcpy (STRINGBUF_CHARS (my_buf), - STRINGBUF_CHARS (buf) + str_start + start, len); + if (scm_i_is_narrow_string (str)) + { + my_buf = make_stringbuf (len); + memcpy (STRINGBUF_CHARS (my_buf), + STRINGBUF_CHARS (buf) + str_start + start, len); + } + else + { + my_buf = make_wide_stringbuf (len); + u32_cpy ((scm_t_uint32 *) STRINGBUF_WIDE_CHARS (my_buf), + (scm_t_uint32 *) (STRINGBUF_WIDE_CHARS (buf) + str_start + + start), len); + /* Even though this string is wide, the substring may be narrow. + Consider adding code to narrow the string. */ + } scm_remember_upto_here_1 (buf); - return scm_double_cell (STRING_TAG, SCM_UNPACK(my_buf), - (scm_t_bits)0, (scm_t_bits) len); + return scm_double_cell (STRING_TAG, SCM_UNPACK (my_buf), + (scm_t_bits) 0, (scm_t_bits) len); } SCM @@ -296,23 +406,61 @@ scm_c_substring_shared (SCM str, size_t start, size_t end) /* Internal accessors */ +/* Returns the number of characters in STR. This may be different + than the memory size of the string storage. */ size_t scm_i_string_length (SCM str) { return STRING_LENGTH (str); } +/* True if the string is 'narrow', meaning it has a 8-bit Latin-1 + encoding. False if it is 'wide', having a 32-bit UCS-4 + encoding. */ +int +scm_i_is_narrow_string (SCM str) +{ + return !STRINGBUF_WIDE (STRING_STRINGBUF (str)); +} + +/* Returns a pointer to the 8-bit Latin-1 encoded character array of + STR. */ const char * scm_i_string_chars (SCM str) { SCM buf; size_t start; get_str_buf_start (&str, &buf, &start); - return STRINGBUF_CHARS (buf) + start; + if (scm_i_is_narrow_string (str)) + return STRINGBUF_CHARS (buf) + start; + else + scm_misc_error (NULL, "Invalid read access of chars of wide string: ~s", + scm_list_1 (str)); + return NULL; } -char * -scm_i_string_writable_chars (SCM orig_str) +/* Returns a pointer to the 32-bit UCS-4 encoded character array of + STR. */ +const scm_t_wchar * +scm_i_string_wide_chars (SCM str) +{ + SCM buf; + size_t start; + + get_str_buf_start (&str, &buf, &start); + if (!scm_i_is_narrow_string (str)) + return STRINGBUF_WIDE_CHARS (buf) + start; + else + scm_misc_error (NULL, "Invalid read access of chars of narrow string: ~s", + scm_list_1 (str)); +} + +/* If the buffer in ORIG_STR is shared, copy ORIG_STR's characters to + a new string buffer, so that it can be modified without modifying + other strings. Also, lock the string mutex. Later, one must call + scm_i_string_stop_writing to unlock the mutex. */ +SCM +scm_i_string_start_writing (SCM orig_str) { SCM buf, str = orig_str; size_t start; @@ -324,17 +472,28 @@ scm_i_string_writable_chars (SCM orig_str) scm_i_pthread_mutex_lock (&stringbuf_write_mutex); if (STRINGBUF_SHARED (buf)) { - /* Clone stringbuf. */ - + /* Clone the stringbuf. */ size_t len = STRING_LENGTH (str); SCM new_buf; scm_i_pthread_mutex_unlock (&stringbuf_write_mutex); - new_buf = make_stringbuf (len); - memcpy (STRINGBUF_CHARS (new_buf), - STRINGBUF_CHARS (buf) + STRING_START (str), len); + if (scm_i_is_narrow_string (str)) + { + new_buf = make_stringbuf (len); + memcpy (STRINGBUF_CHARS (new_buf), + STRINGBUF_CHARS (buf) + STRING_START (str), len); + } + else + { + new_buf = make_wide_stringbuf (len); + u32_cpy ((scm_t_uint32 *) STRINGBUF_WIDE_CHARS (new_buf), + (scm_t_uint32 *) (STRINGBUF_WIDE_CHARS (buf) + + STRING_START (str)), len); + } + + SET_STRING_STRINGBUF (str, new_buf); start -= STRING_START (str); /* FIXME: The following operations are not atomic, so other threads @@ -350,16 +509,77 @@ scm_i_string_writable_chars (SCM orig_str) scm_i_pthread_mutex_lock (&stringbuf_write_mutex); } - - return STRINGBUF_CHARS (buf) + start; + return orig_str; } +/* Return a pointer to the 8-bit Latin-1 chars of a string. */ +char * +scm_i_string_writable_chars (SCM str) +{ + SCM buf; + size_t start; + + get_str_buf_start (&str, &buf, &start); + if (scm_i_is_narrow_string (str)) + return STRINGBUF_CHARS (buf) + start; + else + scm_misc_error (NULL, "Invalid write access of chars of wide string: ~s", + scm_list_1 (str)); + return NULL; +} + +/* Return a pointer to the UCS-4 codepoints of a string. */ +static scm_t_wchar * +scm_i_string_writable_wide_chars (SCM str) +{ + SCM buf; + size_t start; + + get_str_buf_start (&str, &buf, &start); + if (!scm_i_is_narrow_string (str)) + return STRINGBUF_WIDE_CHARS (buf) + start; + else + scm_misc_error (NULL, "Invalid read access of chars of narrow string: ~s", + scm_list_1 (str)); +} + +/* Unlock the string mutex that was locked when + scm_i_string_start_writing was called. */ void scm_i_string_stop_writing (void) { scm_i_pthread_mutex_unlock (&stringbuf_write_mutex); } +/* Return the Xth character of STR as a UCS-4 codepoint. */ +scm_t_wchar +scm_i_string_ref (SCM str, size_t x) +{ + if (scm_i_is_narrow_string (str)) + return (scm_t_wchar) (unsigned char) (scm_i_string_chars (str)[x]); + else + return scm_i_string_wide_chars (str)[x]; +} + +/* Set the Pth character of STR to UCS-4 codepoint CHR. */ +void +scm_i_string_set_x (SCM str, size_t p, scm_t_wchar chr) +{ + if (chr > 0xFF && scm_i_is_narrow_string (str)) + widen_stringbuf (STRING_STRINGBUF (str)); + + if (scm_i_is_narrow_string (str)) + { + char *dst = scm_i_string_writable_chars (str); + dst[p] = (char) (unsigned char) chr; + } + else + { + scm_t_wchar *dst = scm_i_string_writable_wide_chars (str); + dst[p] = chr; + } +} + /* Symbols. Basic symbol creation and accessing is done here, the rest is in @@ -394,10 +614,21 @@ scm_i_make_symbol (SCM name, scm_t_bits flags, else { /* make new buf. */ - SCM new_buf = make_stringbuf (length); - memcpy (STRINGBUF_CHARS (new_buf), - STRINGBUF_CHARS (buf) + start, length); - buf = new_buf; + if (scm_i_is_narrow_string (name)) + { + SCM new_buf = make_stringbuf (length); + memcpy (STRINGBUF_CHARS (new_buf), + STRINGBUF_CHARS (buf) + start, length); + buf = new_buf; + } + else + { + SCM new_buf = make_wide_stringbuf (length); + u32_cpy ((scm_t_uint32 *) STRINGBUF_WIDE_CHARS (new_buf), + (scm_t_uint32 *) STRINGBUF_WIDE_CHARS (buf) + start, + length); + buf = new_buf; + } } return scm_double_cell (scm_tc7_symbol | flags, SCM_UNPACK (buf), (scm_t_bits) hash, SCM_UNPACK (props)); @@ -426,6 +657,8 @@ scm_i_c_take_symbol (char *name, size_t len, (scm_t_bits) hash, SCM_UNPACK (props)); } +/* Returns the number of characters in SYM. This may be different + from the memory size of SYM. */ size_t scm_i_symbol_length (SCM sym) { @@ -442,11 +675,45 @@ scm_c_symbol_length (SCM sym) } #undef FUNC_NAME +/* True if the name of SYM is stored as a Latin-1 encoded string. + False if it is stored as a 32-bit UCS-4-encoded string. */ +int +scm_i_is_narrow_symbol (SCM sym) +{ + SCM buf; + + buf = SYMBOL_STRINGBUF (sym); + return !STRINGBUF_WIDE (buf); +} + +/* Returns a pointer to the 8-bit Latin-1 encoded character array that + contains the name of SYM. */ const char * scm_i_symbol_chars (SCM sym) { - SCM buf = SYMBOL_STRINGBUF (sym); - return STRINGBUF_CHARS (buf); + SCM buf; + + buf = SYMBOL_STRINGBUF (sym); + if (!STRINGBUF_WIDE (buf)) + return STRINGBUF_CHARS (buf); + else + scm_misc_error (NULL, "Invalid access of chars of a wide symbol ~S", + scm_list_1 (sym)); +} + +/* Return a pointer to the 32-bit UCS-4-encoded character array of a + symbol's name. */ +const scm_t_wchar * +scm_i_symbol_wide_chars (SCM sym) +{ + SCM buf; + + buf = SYMBOL_STRINGBUF (sym); + if (STRINGBUF_WIDE (buf)) + return STRINGBUF_WIDE_CHARS (buf); + else + scm_misc_error (NULL, "Invalid access of chars of a narrow symbol ~S", + scm_list_1 (sym)); } SCM @@ -460,64 +727,212 @@ scm_i_symbol_substring (SCM sym, size_t start, size_t end) (scm_t_bits)start, (scm_t_bits) end - start); } +/* Returns the Xth character of symbol SYM as a UCS-4 codepoint. */ +scm_t_wchar +scm_i_symbol_ref (SCM sym, size_t x) +{ + if (scm_i_is_narrow_symbol (sym)) + return (scm_t_wchar) (unsigned char) (scm_i_symbol_chars (sym)[x]); + else + return scm_i_symbol_wide_chars (sym)[x]; +} + /* Debugging */ -#if SCM_DEBUG - -SCM scm_sys_string_dump (SCM); -SCM scm_sys_symbol_dump (SCM); -SCM scm_sys_stringbuf_hist (void); - -SCM_DEFINE (scm_sys_string_dump, "%string-dump", 1, 0, 0, - (SCM str), - "") +SCM_DEFINE (scm_sys_string_dump, "%string-dump", 1, 0, 0, (SCM str), + "Returns an association list containing debugging information\n" + "for @var{str}. The association list has the following entries." + "@table @code\n" + "@item string\n" + "The string itself.\n" + "@item start\n" + "The start index of the string into its stringbuf\n" + "@item length\n" + "The length of the string\n" + "@item shared\n" + "If this string is a substring, it returns its parent string.\n" + "Otherwise, it returns @code{#f}\n" + "@item read-only\n" + "@code{#t} if the string is read-only\n" + "@item stringbuf-chars\n" + "A new string containing this string's stringbuf's characters\n" + "@item stringbuf-length\n" + "The number of characters in this stringbuf\n" + "@item stringbuf-shared\n" + "@code{#t} if this stringbuf is shared\n" + "@item stringbuf-inline\n" + "@code{#t} if this stringbuf's characters are stored in the\n" + "cell itself, or @code{#f} if they were allocated in memory\n" + "@item stringbuf-wide\n" + "@code{#t} if this stringbuf's characters are stored in a\n" + "32-bit buffer, or @code{#f} if they are stored in an 8-bit\n" + "buffer\n" + "@end table") #define FUNC_NAME s_scm_sys_string_dump { + SCM e1, e2, e3, e4, e5, e6, e7, e8, e9, e10; + SCM buf; SCM_VALIDATE_STRING (1, str); - fprintf (stderr, "%p:\n", str); - fprintf (stderr, " start: %u\n", STRING_START (str)); - fprintf (stderr, " len: %u\n", STRING_LENGTH (str)); + + /* String info */ + e1 = scm_cons (scm_from_locale_symbol ("string"), + str); + e2 = scm_cons (scm_from_locale_symbol ("start"), + scm_from_size_t (STRING_START (str))); + e3 = scm_cons (scm_from_locale_symbol ("length"), + scm_from_size_t (STRING_LENGTH (str))); + if (IS_SH_STRING (str)) { - fprintf (stderr, " string: %p\n", SH_STRING_STRING (str)); - fprintf (stderr, "\n"); - scm_sys_string_dump (SH_STRING_STRING (str)); + e4 = scm_cons (scm_from_locale_symbol ("shared"), + SH_STRING_STRING (str)); + buf = STRING_STRINGBUF (SH_STRING_STRING (str)); } else { - SCM buf = STRING_STRINGBUF (str); - fprintf (stderr, " buf: %p\n", buf); - fprintf (stderr, " chars: %p\n", STRINGBUF_CHARS (buf)); - fprintf (stderr, " length: %u\n", STRINGBUF_LENGTH (buf)); - fprintf (stderr, " flags: %x\n", (SCM_CELL_WORD_0 (buf) & 0x300)); + e4 = scm_cons (scm_from_locale_symbol ("shared"), + SCM_BOOL_F); + buf = STRING_STRINGBUF (str); } - return SCM_UNSPECIFIED; + + if (IS_RO_STRING (str)) + e5 = scm_cons (scm_from_locale_symbol ("read-only"), + SCM_BOOL_T); + else + e5 = scm_cons (scm_from_locale_symbol ("read-only"), + SCM_BOOL_F); + + /* Stringbuf info */ + if (!STRINGBUF_WIDE (buf)) + { + size_t len = STRINGBUF_LENGTH (buf); + char *cbuf; + SCM sbc = scm_i_make_string (len, &cbuf); + memcpy (cbuf, STRINGBUF_CHARS (buf), len); + e6 = scm_cons (scm_from_locale_symbol ("stringbuf-chars"), + sbc); + } + else + { + size_t len = STRINGBUF_LENGTH (buf); + scm_t_wchar *cbuf; + SCM sbc = scm_i_make_wide_string (len, &cbuf); + u32_cpy ((scm_t_uint32 *) cbuf, + (scm_t_uint32 *) STRINGBUF_WIDE_CHARS (buf), len); + e6 = scm_cons (scm_from_locale_symbol ("stringbuf-chars"), + sbc); + } + e7 = scm_cons (scm_from_locale_symbol ("stringbuf-length"), + scm_from_size_t (STRINGBUF_LENGTH (buf))); + if (STRINGBUF_SHARED (buf)) + e8 = scm_cons (scm_from_locale_symbol ("stringbuf-shared"), + SCM_BOOL_T); + else + e8 = scm_cons (scm_from_locale_symbol ("stringbuf-shared"), + SCM_BOOL_F); + if (STRINGBUF_INLINE (buf)) + e9 = scm_cons (scm_from_locale_symbol ("stringbuf-inline"), + SCM_BOOL_T); + else + e9 = scm_cons (scm_from_locale_symbol ("stringbuf-inline"), + SCM_BOOL_F); + if (STRINGBUF_WIDE (buf)) + e10 = scm_cons (scm_from_locale_symbol ("stringbuf-wide"), + SCM_BOOL_T); + else + e10 = scm_cons (scm_from_locale_symbol ("stringbuf-wide"), + SCM_BOOL_F); + + return scm_list_n (e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, SCM_UNDEFINED); } #undef FUNC_NAME -SCM_DEFINE (scm_sys_symbol_dump, "%symbol-dump", 1, 0, 0, - (SCM sym), - "") +SCM_DEFINE (scm_sys_symbol_dump, "%symbol-dump", 1, 0, 0, (SCM sym), + "Returns an association list containing debugging information\n" + "for @var{sym}. The association list has the following entries." + "@table @code\n" + "@item symbol\n" + "The symbol itself\n" + "@item hash\n" + "Its hash value\n" + "@item interned\n" + "@code{#t} if it is an interned symbol\n" + "@item stringbuf-chars\n" + "A new string containing this symbols's stringbuf's characters\n" + "@item stringbuf-length\n" + "The number of characters in this stringbuf\n" + "@item stringbuf-shared\n" + "@code{#t} if this stringbuf is shared\n" + "@item stringbuf-inline\n" + "@code{#t} if this stringbuf's characters are stored in the\n" + "cell itself, or @code{#f} if they were allocated in memory\n" + "@item stringbuf-wide\n" + "@code{#t} if this stringbuf's characters are stored in a\n" + "32-bit buffer, or @code{#f} if they are stored in an 8-bit\n" + "buffer\n" + "@end table") #define FUNC_NAME s_scm_sys_symbol_dump { + SCM e1, e2, e3, e4, e5, e6, e7, e8; + SCM buf; SCM_VALIDATE_SYMBOL (1, sym); - fprintf (stderr, "%p:\n", sym); - fprintf (stderr, " hash: %lu\n", scm_i_symbol_hash (sym)); - { - SCM buf = SYMBOL_STRINGBUF (sym); - fprintf (stderr, " buf: %p\n", buf); - fprintf (stderr, " chars: %p\n", STRINGBUF_CHARS (buf)); - fprintf (stderr, " length: %u\n", STRINGBUF_LENGTH (buf)); - fprintf (stderr, " shared: %u\n", STRINGBUF_SHARED (buf)); - } - return SCM_UNSPECIFIED; + e1 = scm_cons (scm_from_locale_symbol ("symbol"), + sym); + e2 = scm_cons (scm_from_locale_symbol ("hash"), + scm_from_ulong (scm_i_symbol_hash (sym))); + e3 = scm_cons (scm_from_locale_symbol ("interned"), + scm_symbol_interned_p (sym)); + buf = SYMBOL_STRINGBUF (sym); + + /* Stringbuf info */ + if (!STRINGBUF_WIDE (buf)) + { + size_t len = STRINGBUF_LENGTH (buf); + char *cbuf; + SCM sbc = scm_i_make_string (len, &cbuf); + memcpy (cbuf, STRINGBUF_CHARS (buf), len); + e4 = scm_cons (scm_from_locale_symbol ("stringbuf-chars"), + sbc); + } + else + { + size_t len = STRINGBUF_LENGTH (buf); + scm_t_wchar *cbuf; + SCM sbc = scm_i_make_wide_string (len, &cbuf); + u32_cpy ((scm_t_uint32 *) cbuf, + (scm_t_uint32 *) STRINGBUF_WIDE_CHARS (buf), len); + e4 = scm_cons (scm_from_locale_symbol ("stringbuf-chars"), + sbc); + } + e5 = scm_cons (scm_from_locale_symbol ("stringbuf-length"), + scm_from_size_t (STRINGBUF_LENGTH (buf))); + if (STRINGBUF_SHARED (buf)) + e6 = scm_cons (scm_from_locale_symbol ("stringbuf-shared"), + SCM_BOOL_T); + else + e6 = scm_cons (scm_from_locale_symbol ("stringbuf-shared"), + SCM_BOOL_F); + if (STRINGBUF_INLINE (buf)) + e7 = scm_cons (scm_from_locale_symbol ("stringbuf-inline"), + SCM_BOOL_T); + else + e7 = scm_cons (scm_from_locale_symbol ("stringbuf-inline"), + SCM_BOOL_F); + if (STRINGBUF_WIDE (buf)) + e8 = scm_cons (scm_from_locale_symbol ("stringbuf-wide"), + SCM_BOOL_T); + else + e8 = scm_cons (scm_from_locale_symbol ("stringbuf-wide"), + SCM_BOOL_F); + return scm_list_n (e1, e2, e3, e4, e5, e6, e7, e8, SCM_UNDEFINED); + } #undef FUNC_NAME -SCM_DEFINE (scm_sys_stringbuf_hist, "%stringbuf-hist", 0, 0, 0, - (void), - "") +#if SCM_STRING_LENGTH_HISTOGRAM + +SCM_DEFINE (scm_sys_stringbuf_hist, "%stringbuf-hist", 0, 0, 0, (void), "") #define FUNC_NAME s_scm_sys_stringbuf_hist { int i; @@ -553,29 +968,47 @@ SCM_DEFINE (scm_string, "string", 0, 0, 1, #define FUNC_NAME s_scm_string { SCM result; + SCM rest; size_t len; - char *data; + size_t p = 0; + long i; - { - long i = scm_ilength (chrs); + /* Verify that this is a list of chars. */ + i = scm_ilength (chrs); + SCM_ASSERT (i >= 0, chrs, SCM_ARG1, FUNC_NAME); - SCM_ASSERT (i >= 0, chrs, SCM_ARG1, FUNC_NAME); - len = i; - } + len = (size_t) i; + rest = chrs; - result = scm_i_make_string (len, &data); - while (len > 0 && scm_is_pair (chrs)) + while (len > 0 && scm_is_pair (rest)) { - SCM elt = SCM_CAR (chrs); - + SCM elt = SCM_CAR (rest); SCM_VALIDATE_CHAR (SCM_ARGn, elt); - *data++ = SCM_CHAR (elt); - chrs = SCM_CDR (chrs); + rest = SCM_CDR (rest); len--; + scm_remember_upto_here_1 (elt); } + + /* Construct a string containing this list of chars. */ + len = (size_t) i; + rest = chrs; + + result = scm_i_make_string (len, NULL); + result = scm_i_string_start_writing (result); + while (len > 0 && scm_is_pair (rest)) + { + SCM elt = SCM_CAR (rest); + scm_i_string_set_x (result, p, SCM_CHAR (elt)); + p++; + rest = SCM_CDR (rest); + len--; + scm_remember_upto_here_1 (elt); + } + scm_i_string_stop_writing (); + if (len > 0) scm_misc_error (NULL, "list changed while constructing string", SCM_EOL); - if (!scm_is_null (chrs)) + if (!scm_is_null (rest)) scm_wrong_type_arg_msg (NULL, 0, chrs, "proper list"); return result; @@ -598,13 +1031,16 @@ SCM scm_c_make_string (size_t len, SCM chr) #define FUNC_NAME NULL { - char *dst; - SCM res = scm_i_make_string (len, &dst); + size_t p; + SCM res = scm_i_make_string (len, NULL); if (!SCM_UNBNDP (chr)) { SCM_VALIDATE_CHAR (0, chr); - memset (dst, SCM_CHAR (chr), len); + res = scm_i_string_start_writing (res); + for (p = 0; p < len; p++) + scm_i_string_set_x (res, p, SCM_CHAR (chr)); + scm_i_string_stop_writing (); } return res; @@ -621,6 +1057,20 @@ SCM_DEFINE (scm_string_length, "string-length", 1, 0, 0, } #undef FUNC_NAME +SCM_DEFINE (scm_string_width, "string-width", 1, 0, 0, + (SCM string), + "Return the bytes used to represent a character in @var{string}." + "This will return 1 or 4.") +#define FUNC_NAME s_scm_string_width +{ + SCM_VALIDATE_STRING (1, string); + if (!scm_i_is_narrow_string (string)) + return scm_from_int (4); + + return scm_from_int (1); +} +#undef FUNC_NAME + size_t scm_c_string_length (SCM string) { @@ -631,8 +1081,8 @@ scm_c_string_length (SCM string) SCM_DEFINE (scm_string_ref, "string-ref", 2, 0, 0, (SCM str, SCM k), - "Return character @var{k} of @var{str} using zero-origin\n" - "indexing. @var{k} must be a valid index of @var{str}.") + "Return character @var{k} of @var{str} using zero-origin\n" + "indexing. @var{k} must be a valid index of @var{str}.") #define FUNC_NAME s_scm_string_ref { size_t len; @@ -646,7 +1096,10 @@ SCM_DEFINE (scm_string_ref, "string-ref", 2, 0, 0, else scm_out_of_range (NULL, k); - return SCM_MAKE_CHAR (scm_i_string_chars (str)[idx]); + if (scm_i_is_narrow_string (str)) + return SCM_MAKE_CHAR (scm_i_string_chars (str)[idx]); + else + return SCM_MAKE_CHAR (scm_i_string_wide_chars (str)[idx]); } #undef FUNC_NAME @@ -655,14 +1108,18 @@ scm_c_string_ref (SCM str, size_t p) { if (p >= scm_i_string_length (str)) scm_out_of_range (NULL, scm_from_size_t (p)); - return SCM_MAKE_CHAR (scm_i_string_chars (str)[p]); + if (scm_i_is_narrow_string (str)) + return SCM_MAKE_CHAR (scm_i_string_chars (str)[p]); + else + return SCM_MAKE_CHAR (scm_i_string_wide_chars (str)[p]); + } SCM_DEFINE (scm_string_set_x, "string-set!", 3, 0, 0, (SCM str, SCM k, SCM chr), - "Store @var{chr} in element @var{k} of @var{str} and return\n" - "an unspecified value. @var{k} must be a valid index of\n" - "@var{str}.") + "Store @var{chr} in element @var{k} of @var{str} and return\n" + "an unspecified value. @var{k} must be a valid index of\n" + "@var{str}.") #define FUNC_NAME s_scm_string_set_x { size_t len; @@ -677,11 +1134,10 @@ SCM_DEFINE (scm_string_set_x, "string-set!", 3, 0, 0, scm_out_of_range (NULL, k); SCM_VALIDATE_CHAR (3, chr); - { - char *dst = scm_i_string_writable_chars (str); - dst[idx] = SCM_CHAR (chr); - scm_i_string_stop_writing (); - } + str = scm_i_string_start_writing (str); + scm_i_string_set_x (str, idx, SCM_CHAR (chr)); + scm_i_string_stop_writing (); + return SCM_UNSPECIFIED; } #undef FUNC_NAME @@ -691,11 +1147,9 @@ scm_c_string_set_x (SCM str, size_t p, SCM chr) { if (p >= scm_i_string_length (str)) scm_out_of_range (NULL, scm_from_size_t (p)); - { - char *dst = scm_i_string_writable_chars (str); - dst[p] = SCM_CHAR (chr); - scm_i_string_stop_writing (); - } + str = scm_i_string_start_writing (str); + scm_i_string_set_x (str, p, SCM_CHAR (chr)); + scm_i_string_stop_writing (); } SCM_DEFINE (scm_substring, "substring", 2, 1, 0, @@ -796,31 +1250,59 @@ SCM_DEFINE (scm_substring_shared, "substring/shared", 2, 1, 0, SCM_DEFINE (scm_string_append, "string-append", 0, 0, 1, (SCM args), - "Return a newly allocated string whose characters form the\n" + "Return a newly allocated string whose characters form the\n" "concatenation of the given strings, @var{args}.") #define FUNC_NAME s_scm_string_append { SCM res; - size_t i = 0; + size_t len = 0; + int wide = 0; SCM l, s; - char *data; + size_t i; + union + { + char *narrow; + scm_t_wchar *wide; + } data; SCM_VALIDATE_REST_ARGUMENT (args); - for (l = args; !scm_is_null (l); l = SCM_CDR (l)) + for (l = args; !scm_is_null (l); l = SCM_CDR (l)) { s = SCM_CAR (l); SCM_VALIDATE_STRING (SCM_ARGn, s); - i += scm_i_string_length (s); + len += scm_i_string_length (s); + if (!scm_i_is_narrow_string (s)) + wide = 1; } - res = scm_i_make_string (i, &data); - for (l = args; !scm_is_null (l); l = SCM_CDR (l)) + data.narrow = NULL; + if (!wide) + res = scm_i_make_string (len, &data.narrow); + else + res = scm_i_make_wide_string (len, &data.wide); + + for (l = args; !scm_is_null (l); l = SCM_CDR (l)) { size_t len; s = SCM_CAR (l); SCM_VALIDATE_STRING (SCM_ARGn, s); len = scm_i_string_length (s); - memcpy (data, scm_i_string_chars (s), len); - data += len; + if (!wide) + { + memcpy (data.narrow, scm_i_string_chars (s), len); + data.narrow += len; + } + else + { + if (scm_i_is_narrow_string (s)) + { + for (i = 0; i < scm_i_string_length (s); i++) + data.wide[i] = (unsigned char) scm_i_string_chars (s)[i]; + } + else + u32_cpy ((scm_t_uint32 *) data.wide, + (scm_t_uint32 *) scm_i_string_wide_chars (s), len); + data.wide += len; + } scm_remember_upto_here_1 (s); } return res; @@ -839,8 +1321,11 @@ scm_from_locale_stringn (const char *str, size_t len) SCM res; char *dst; - if (len == (size_t)-1) + if (len == (size_t) -1) len = strlen (str); + if (len == 0) + return scm_nullstr; + res = scm_i_make_string (len, &dst); memcpy (dst, str, len); return res; @@ -849,29 +1334,33 @@ scm_from_locale_stringn (const char *str, size_t len) SCM scm_from_locale_string (const char *str) { + if (str == NULL) + return scm_nullstr; + return scm_from_locale_stringn (str, -1); } +/* Create a new scheme string from the C string STR. The memory of + STR may be used directly as storage for the new string. */ SCM scm_take_locale_stringn (char *str, size_t len) { SCM buf, res; - if (len == (size_t)-1) + if (len == (size_t) -1) len = strlen (str); else { /* Ensure STR is null terminated. A realloc for 1 extra byte should often be satisfied from the alignment padding after the block, with no actual data movement. */ - str = scm_realloc (str, len+1); + str = scm_realloc (str, len + 1); str[len] = '\0'; } buf = scm_i_take_stringbufn (str, len); res = scm_double_cell (STRING_TAG, - SCM_UNPACK (buf), - (scm_t_bits) 0, (scm_t_bits) len); + SCM_UNPACK (buf), (scm_t_bits) 0, (scm_t_bits) len); return res; } @@ -881,33 +1370,144 @@ scm_take_locale_string (char *str) return scm_take_locale_stringn (str, -1); } -char * -scm_to_locale_stringn (SCM str, size_t *lenp) +/* Change libunistring escapes (\uXXXX and \UXXXXXXXX) to \xXX \uXXXX + and \UXXXXXX. */ +static void +unistring_escapes_to_guile_escapes (char **bufp, size_t *lenp) { - char *res; - size_t len; + char *before, *after; + size_t i, j; + + before = *bufp; + after = *bufp; + i = 0; + j = 0; + while (i < *lenp) + { + if ((i <= *lenp - 6) + && before[i] == '\\' + && before[i + 1] == 'u' + && before[i + 2] == '0' && before[i + 3] == '0') + { + /* Convert \u00NN to \xNN */ + after[j] = '\\'; + after[j + 1] = 'x'; + after[j + 2] = tolower ((int) before[i + 4]); + after[j + 3] = tolower ((int) before[i + 5]); + i += 6; + j += 4; + } + else if ((i <= *lenp - 10) + && before[i] == '\\' + && before[i + 1] == 'U' + && before[i + 2] == '0' && before[i + 3] == '0') + { + /* Convert \U00NNNNNN to \UNNNNNN */ + after[j] = '\\'; + after[j + 1] = 'U'; + after[j + 2] = tolower ((int) before[i + 4]); + after[j + 3] = tolower ((int) before[i + 5]); + after[j + 4] = tolower ((int) before[i + 6]); + after[j + 5] = tolower ((int) before[i + 7]); + after[j + 6] = tolower ((int) before[i + 8]); + after[j + 7] = tolower ((int) before[i + 9]); + i += 10; + j += 8; + } + else + { + after[j] = before[i]; + i++; + j++; + } + } + *lenp = j; + after = scm_realloc (after, j); +} + +char * +scm_to_locale_stringn (SCM str, size_t * lenp) +{ + const char *enc; + + /* In the future, enc will hold the port's encoding. */ + enc = NULL; + + return scm_to_stringn (str, lenp, enc, + SCM_FAILED_CONVERSION_ESCAPE_SEQUENCE); +} + +/* Low-level scheme to C string conversion function. */ +char * +scm_to_stringn (SCM str, size_t * lenp, const char *encoding, + scm_t_string_failed_conversion_handler handler) +{ + static const char iso[11] = "ISO-8859-1"; + char *buf; + size_t ilen, len, i; if (!scm_is_string (str)) scm_wrong_type_arg_msg (NULL, 0, str, "string"); - len = scm_i_string_length (str); - res = scm_malloc (len + ((lenp==NULL)? 1 : 0)); - memcpy (res, scm_i_string_chars (str), len); - if (lenp == NULL) + ilen = scm_i_string_length (str); + + if (ilen == 0) { - res[len] = '\0'; - if (strlen (res) != len) - { - free (res); - scm_misc_error (NULL, - "string contains #\\nul character: ~S", - scm_list_1 (str)); - } + buf = scm_malloc (1); + buf[0] = '\0'; + if (lenp) + *lenp = 0; + return buf; } - else + + if (lenp == NULL) + for (i = 0; i < ilen; i++) + if (scm_i_string_ref (str, i) == '\0') + scm_misc_error (NULL, + "string contains #\\nul character: ~S", + scm_list_1 (str)); + + if (scm_i_is_narrow_string (str)) + { + if (lenp) + { + buf = scm_malloc (ilen); + memcpy (buf, scm_i_string_chars (str), ilen); + *lenp = ilen; + return buf; + } + else + { + buf = scm_malloc (ilen + 1); + memcpy (buf, scm_i_string_chars (str), ilen); + buf[ilen] = '\0'; + return buf; + } + } + + + buf = NULL; + len = 0; + buf = u32_conv_to_encoding (iso, + (enum iconv_ilseq_handler) handler, + (scm_t_uint32 *) scm_i_string_wide_chars (str), + ilen, NULL, NULL, &len); + if (buf == NULL) + scm_misc_error (NULL, "cannot convert to output locale ~s: \"~s\"", + scm_list_2 (scm_from_locale_string (iso), str)); + + if (handler == SCM_FAILED_CONVERSION_ESCAPE_SEQUENCE) + unistring_escapes_to_guile_escapes (&buf, &len); + + if (lenp) *lenp = len; + else + { + buf = scm_realloc (buf, len + 1); + buf[len] = '\0'; + } scm_remember_upto_here_1 (str); - return res; + return buf; } char * @@ -920,18 +1520,21 @@ size_t scm_to_locale_stringbuf (SCM str, char *buf, size_t max_len) { size_t len; - + char *result = NULL; if (!scm_is_string (str)) scm_wrong_type_arg_msg (NULL, 0, str, "string"); - len = scm_i_string_length (str); - memcpy (buf, scm_i_string_chars (str), (len > max_len)? max_len : len); + result = scm_to_locale_stringn (str, &len); + + memcpy (buf, result, (len > max_len) ? max_len : len); + free (result); + scm_remember_upto_here_1 (str); return len; } /* converts C scm_array of strings to SCM scm_list of strings. */ /* If argc < 0, a null terminated scm_array is assumed. */ -SCM +SCM scm_makfromstrs (int argc, char **argv) { int i = argc; @@ -1032,7 +1635,7 @@ scm_i_deprecated_string_chars (SCM str) "SCM_STRING_CHARS does not work with shared substrings.", SCM_EOL); - /* We explicitely test for read-only strings to produce a better + /* We explicitly test for read-only strings to produce a better error message. */ @@ -1043,6 +1646,7 @@ scm_i_deprecated_string_chars (SCM str) /* The following is still wrong, of course... */ + str = scm_i_string_start_writing (str); chars = scm_i_string_writable_chars (str); scm_i_string_stop_writing (); return chars; diff --git a/libguile/strings.h b/libguile/strings.h index e7053257f..c3e3e6ac8 100644 --- a/libguile/strings.h +++ b/libguile/strings.h @@ -3,21 +3,22 @@ #ifndef SCM_STRINGS_H #define SCM_STRINGS_H -/* Copyright (C) 1995,1996,1997,1998,2000,2001, 2004, 2005, 2006, 2008 Free Software Foundation, Inc. +/* Copyright (C) 1995,1996,1997,1998,2000,2001, 2004, 2005, 2006, 2008, 2009 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ @@ -45,26 +46,37 @@ Internal, low level interface to the character arrays - - Use scm_i_string_chars to get a pointer to the byte array of a - string for reading. Use scm_i_string_length to get the number of - bytes in that array. The array is not null-terminated. + - Use scm_is_narrow_string to determine is the string is narrow or + wide. + + - Use scm_i_string_chars or scm_i_string_wide_chars to get a + pointer to the byte or scm_t_wchar array of a string for reading. + Use scm_i_string_length to get the number of characters in that + array. The array is not null-terminated. - The array is valid as long as the corresponding SCM object is protected but only until the next SCM_TICK. During such a 'safe point', strings might change their representation. - - Use scm_i_string_writable_chars to get the same pointer as with - scm_i_string_chars, but for reading and writing. This is a - potentially costly operation since it implements the - copy-on-write behavior. When done with the writing, call - scm_i_string_stop_writing. You must do this before the next - SCM_TICK. (This means, before calling almost any other scm_ - function and you can't allow throws, of course.) + - Use scm_i_string_start_writing to get a version of the string + ready for reading and writing. This is a potentially costly + operation since it implements the copy-on-write behavior. When + done with the writing, call scm_i_string_stop_writing. You must + do this before the next SCM_TICK. (This means, before calling + almost any other scm_ function and you can't allow throws, of + course.) - - New strings can be created with scm_i_make_string. This gives - access to a writable pointer that remains valid as long as nobody - else makes a copy-on-write substring of the string. Do not call - scm_i_string_stop_writing for this pointer. + - New strings can be created with scm_i_make_string or + scm_i_make_wide_string. This gives access to a writable pointer + that remains valid as long as nobody else makes a copy-on-write + substring of the string. Do not call scm_i_string_stop_writing + for this pointer. + + - Alternately, scm_i_string_ref and scm_i_string_set_x can be used + to read and write strings without worrying about whether the + string is narrow or wide. scm_i_string_set_x still needs to be + bracketed by scm_i_string_start_writing and + scm_i_string_stop_writing. Legacy interface @@ -73,13 +85,24 @@ - SCM_STRING_CHARS uses scm_i_string_writable_chars and immediately calls scm_i_stop_writing, hoping for the best. SCM_STRING_LENGTH is the same as scm_i_string_length. SCM_STRING_CHARS will throw - an error for for strings that are not null-terminated. + an error for for strings that are not null-terminated. There is + no wide version of this interface. */ +/* A type indicating what strategy to take when string locale + conversion is unsuccessful. */ +typedef enum +{ + SCM_FAILED_CONVERSION_ERROR = SCM_ICONVEH_ERROR, + SCM_FAILED_CONVERSION_QUESTION_MARK = SCM_ICONVEH_QUESTION_MARK, + SCM_FAILED_CONVERSION_ESCAPE_SEQUENCE = SCM_ICONVEH_ESCAPE_SEQUENCE +} scm_t_string_failed_conversion_handler; + SCM_API SCM scm_string_p (SCM x); SCM_API SCM scm_string (SCM chrs); SCM_API SCM scm_make_string (SCM k, SCM chr); SCM_API SCM scm_string_length (SCM str); +SCM_API SCM scm_string_width (SCM str); SCM_API SCM scm_string_ref (SCM str, SCM k); SCM_API SCM scm_string_set_x (SCM str, SCM k, SCM chr); SCM_API SCM scm_substring (SCM str, SCM start, SCM end); @@ -105,6 +128,10 @@ SCM_API SCM scm_take_locale_string (char *str); SCM_API SCM scm_take_locale_stringn (char *str, size_t len); SCM_API char *scm_to_locale_string (SCM str); SCM_API char *scm_to_locale_stringn (SCM str, size_t *lenp); +SCM_INTERNAL char *scm_to_stringn (SCM str, size_t *lenp, + const char *encoding, + scm_t_string_failed_conversion_handler + handler); SCM_API size_t scm_to_locale_stringbuf (SCM str, char *buf, size_t max_len); SCM_API SCM scm_makfromstrs (int argc, char **argv); @@ -112,6 +139,7 @@ SCM_API SCM scm_makfromstrs (int argc, char **argv); /* internal accessor functions. Arguments must be valid. */ SCM_INTERNAL SCM scm_i_make_string (size_t len, char **datap); +SCM_INTERNAL SCM scm_i_make_wide_string (size_t len, scm_t_wchar **datap); SCM_INTERNAL SCM scm_i_substring (SCM str, size_t start, size_t end); SCM_INTERNAL SCM scm_i_substring_read_only (SCM str, size_t start, size_t end); SCM_INTERNAL SCM scm_i_substring_shared (SCM str, size_t start, size_t end); @@ -119,8 +147,12 @@ SCM_INTERNAL SCM scm_i_substring_copy (SCM str, size_t start, size_t end); SCM_INTERNAL size_t scm_i_string_length (SCM str); SCM_API /* FIXME: not internal */ const char *scm_i_string_chars (SCM str); SCM_API /* FIXME: not internal */ char *scm_i_string_writable_chars (SCM str); +SCM_INTERNAL const scm_t_wchar *scm_i_string_wide_chars (SCM str); +SCM_INTERNAL SCM scm_i_string_start_writing (SCM str); SCM_INTERNAL void scm_i_string_stop_writing (void); - +SCM_INTERNAL int scm_i_is_narrow_string (SCM str); +SCM_INTERNAL scm_t_wchar scm_i_string_ref (SCM str, size_t x); +SCM_INTERNAL void scm_i_string_set_x (SCM str, size_t p, scm_t_wchar chr); /* internal functions related to symbols. */ SCM_INTERNAL SCM scm_i_make_symbol (SCM name, scm_t_bits flags, @@ -132,8 +164,11 @@ SCM_INTERNAL SCM scm_i_c_take_symbol (char *name, size_t len, scm_t_bits flags, unsigned long hash, SCM props); SCM_INTERNAL const char *scm_i_symbol_chars (SCM sym); +SCM_INTERNAL const scm_t_wchar *scm_i_symbol_wide_chars (SCM sym); SCM_INTERNAL size_t scm_i_symbol_length (SCM sym); +SCM_INTERNAL int scm_i_is_narrow_symbol (SCM str); SCM_INTERNAL SCM scm_i_symbol_substring (SCM sym, size_t start, size_t end); +SCM_INTERNAL scm_t_wchar scm_i_symbol_ref (SCM sym, size_t x); /* internal utility functions. */ @@ -143,6 +178,14 @@ SCM_INTERNAL void scm_i_get_substring_spec (size_t len, SCM end, size_t *cend); SCM_INTERNAL SCM scm_i_take_stringbufn (char *str, size_t len); +/* Debugging functions */ + +SCM_API SCM scm_sys_string_dump (SCM); +SCM_API SCM scm_sys_symbol_dump (SCM); +#if SCM_STRING_LENGTH_HISTOGRAM +SCM_API SCM scm_sys_stringbuf_hist (void); +#endif + /* deprecated stuff */ #if SCM_ENABLE_DEPRECATED diff --git a/libguile/strorder.c b/libguile/strorder.c index d3ccfcb06..e0a218389 100644 --- a/libguile/strorder.c +++ b/libguile/strorder.c @@ -1,18 +1,19 @@ /* Copyright (C) 1995, 1996, 1999, 2000, 2004, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/strorder.h b/libguile/strorder.h index 17118634e..2c004e48a 100644 --- a/libguile/strorder.h +++ b/libguile/strorder.h @@ -6,18 +6,19 @@ /* Copyright (C) 1995,1996,2000, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/strports.c b/libguile/strports.c index bc3fd7014..5c67bf9a8 100644 --- a/libguile/strports.c +++ b/libguile/strports.c @@ -1,18 +1,19 @@ -/* Copyright (C) 1995,1996,1998,1999,2000,2001,2002, 2003, 2005, 2006 Free Software Foundation, Inc. +/* Copyright (C) 1995,1996,1998,1999,2000,2001,2002, 2003, 2005, 2006, 2009 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ @@ -107,7 +108,7 @@ stfill_buffer (SCM port) /* change the size of a port's string to new_size. this doesn't change read_buf_size. */ static void -st_resize_port (scm_t_port *pt, off_t new_size) +st_resize_port (scm_t_port *pt, scm_t_off new_size) { SCM old_stream = SCM_PACK (pt->stream); const char *src = scm_i_string_chars (old_stream); @@ -117,7 +118,7 @@ st_resize_port (scm_t_port *pt, off_t new_size) unsigned long int min_size = min (old_size, new_size); unsigned long int i; - off_t index = pt->write_pos - pt->write_buf; + scm_t_off index = pt->write_pos - pt->write_buf; pt->write_buf_size = new_size; @@ -198,11 +199,11 @@ st_end_input (SCM port, int offset) pt->rw_active = SCM_PORT_NEITHER; } -static off_t -st_seek (SCM port, off_t offset, int whence) +static scm_t_off +st_seek (SCM port, scm_t_off offset, int whence) { scm_t_port *pt = SCM_PTAB_ENTRY (port); - off_t target; + scm_t_off target; if (pt->rw_active == SCM_PORT_READ && offset == 0 && whence == SEEK_CUR) /* special case to avoid disturbing the unread-char buffer. */ @@ -271,7 +272,7 @@ st_seek (SCM port, off_t offset, int whence) } static void -st_truncate (SCM port, off_t length) +st_truncate (SCM port, scm_t_off length) { scm_t_port *pt = SCM_PTAB_ENTRY (port); diff --git a/libguile/strports.h b/libguile/strports.h index 58ca71f57..3129c03e2 100644 --- a/libguile/strports.h +++ b/libguile/strports.h @@ -6,18 +6,19 @@ /* Copyright (C) 1995,1996,2000,2001,2002, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/struct.c b/libguile/struct.c index b536bea3b..062b5245d 100644 --- a/libguile/struct.c +++ b/libguile/struct.c @@ -1,18 +1,19 @@ /* Copyright (C) 1996,1997,1998,1999,2000,2001, 2003, 2004, 2006, 2007, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/struct.h b/libguile/struct.h index cccf429ec..12069b487 100644 --- a/libguile/struct.h +++ b/libguile/struct.h @@ -6,18 +6,19 @@ /* Copyright (C) 1995,1997,1999,2000,2001, 2006, 2007, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/symbols.c b/libguile/symbols.c index a15dfa43c..6faac61ff 100644 --- a/libguile/symbols.c +++ b/libguile/symbols.c @@ -1,18 +1,19 @@ /* Copyright (C) 1995,1996,1997,1998,2000,2001, 2003, 2004, 2006, 2009 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/symbols.h b/libguile/symbols.h index c2dc18363..e4bc33391 100644 --- a/libguile/symbols.h +++ b/libguile/symbols.h @@ -6,18 +6,19 @@ /* Copyright (C) 1995,1996,1997,1998,2000,2001, 2003, 2004, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/tags.h b/libguile/tags.h index 2f30369d9..329453341 100644 --- a/libguile/tags.h +++ b/libguile/tags.h @@ -7,18 +7,19 @@ * Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/threads.c b/libguile/threads.c index fc131790d..250db2cd5 100644 --- a/libguile/threads.c +++ b/libguile/threads.c @@ -1,18 +1,19 @@ /* Copyright (C) 1995,1996,1997,1998,2000,2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ @@ -1180,6 +1181,16 @@ SCM_DEFINE (scm_join_thread_timed, "join-thread", 1, 2, 0, scm_i_pthread_mutex_unlock (&t->admin_mutex); SCM_TICK; scm_i_scm_pthread_mutex_lock (&t->admin_mutex); + + /* Check for exit again, since we just released and + reacquired the admin mutex, before the next block_self + call (which would block forever if t has already + exited). */ + if (t->exited) + { + res = t->result; + break; + } } } @@ -1503,6 +1514,7 @@ fat_mutex_unlock (SCM mutex, SCM cond, { if (relock) scm_lock_mutex_timed (mutex, SCM_UNDEFINED, owner); + t->block_asyncs--; break; } diff --git a/libguile/threads.h b/libguile/threads.h index 6eb1c34c5..d48d530a5 100644 --- a/libguile/threads.h +++ b/libguile/threads.h @@ -6,18 +6,19 @@ /* Copyright (C) 1996,1997,1998,2000,2001, 2002, 2003, 2004, 2006, 2007, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/throw.c b/libguile/throw.c index e0dda27cf..b48bea1d1 100644 --- a/libguile/throw.c +++ b/libguile/throw.c @@ -1,18 +1,19 @@ /* Copyright (C) 1995,1996,1997,1998,2000,2001, 2003, 2004, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/throw.h b/libguile/throw.h index 3cd557285..1ed6ba6b1 100644 --- a/libguile/throw.h +++ b/libguile/throw.h @@ -6,18 +6,19 @@ /* Copyright (C) 1995,1996,1998,2000, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/unif.c b/libguile/unif.c index ecf96dfec..20bc2cfbc 100644 --- a/libguile/unif.c +++ b/libguile/unif.c @@ -1,18 +1,19 @@ -/* Copyright (C) 1995,1996,1997,1998,2000,2001,2002,2003,2004, 2005, 2006 Free Software Foundation, Inc. +/* Copyright (C) 1995,1996,1997,1998,2000,2001,2002,2003,2004, 2005, 2006, 2009 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ @@ -46,6 +47,7 @@ #include "libguile/srfi-13.h" #include "libguile/srfi-4.h" #include "libguile/vectors.h" +#include "libguile/bytevectors.h" #include "libguile/list.h" #include "libguile/deprecation.h" #include "libguile/dynwind.h" @@ -108,6 +110,7 @@ struct { { "f64", SCM_UNSPECIFIED, scm_make_f64vector }, { "c32", SCM_UNSPECIFIED, scm_make_c32vector }, { "c64", SCM_UNSPECIFIED, scm_make_c64vector }, + { "vu8", SCM_UNSPECIFIED, scm_make_bytevector }, { NULL } }; @@ -312,6 +315,12 @@ bitvector_ref (scm_t_array_handle *h, ssize_t pos) scm_from_bool (((scm_t_uint32 *)h->elements)[pos/32] & (1l << (pos % 32))); } +static SCM +bytevector_ref (scm_t_array_handle *h, ssize_t pos) +{ + return scm_from_uint8 (((scm_t_uint8 *) h->elements)[pos]); +} + static SCM memoize_ref (scm_t_array_handle *h, ssize_t pos) { @@ -345,6 +354,11 @@ memoize_ref (scm_t_array_handle *h, ssize_t pos) h->elements = scm_array_handle_bit_elements (h); h->ref = bitvector_ref; } + else if (scm_is_bytevector (v)) + { + h->elements = scm_array_handle_uniform_elements (h); + h->ref = bytevector_ref; + } else scm_misc_error (NULL, "unknown array type: ~a", scm_list_1 (h->array)); @@ -385,6 +399,17 @@ bitvector_set (scm_t_array_handle *h, ssize_t pos, SCM val) ((scm_t_uint32 *)h->writable_elements)[pos/32] &= ~mask; } +static void +bytevector_set (scm_t_array_handle *h, ssize_t pos, SCM val) +{ + scm_t_uint8 c_value; + scm_t_uint8 *elements; + + c_value = scm_to_uint8 (val); + elements = (scm_t_uint8 *) h->elements; + elements[pos] = (scm_t_uint8) c_value; +} + static void memoize_set (scm_t_array_handle *h, ssize_t pos, SCM val) { @@ -419,6 +444,11 @@ memoize_set (scm_t_array_handle *h, ssize_t pos, SCM val) h->writable_elements = scm_array_handle_bit_writable_elements (h); h->set = bitvector_set; } + else if (scm_is_bytevector (v)) + { + h->elements = scm_array_handle_uniform_writable_elements (h); + h->set = bytevector_set; + } else scm_misc_error (NULL, "unknown array type: ~a", scm_list_1 (h->array)); @@ -770,6 +800,53 @@ SCM_DEFINE (scm_make_typed_array, "make-typed-array", 2, 0, 1, } #undef FUNC_NAME +SCM +scm_from_contiguous_typed_array (SCM type, SCM bounds, const void *bytes, + size_t byte_len) +#define FUNC_NAME "scm_from_contiguous_typed_array" +{ + size_t k, rlen = 1; + scm_t_array_dim *s; + creator_proc *creator; + SCM ra; + scm_t_array_handle h; + void *base; + size_t sz; + + creator = type_to_creator (type); + ra = scm_i_shap2ra (bounds); + SCM_SET_ARRAY_CONTIGUOUS_FLAG (ra); + s = SCM_I_ARRAY_DIMS (ra); + k = SCM_I_ARRAY_NDIM (ra); + + while (k--) + { + s[k].inc = rlen; + SCM_ASSERT_RANGE (1, bounds, s[k].lbnd <= s[k].ubnd + 1); + rlen = (s[k].ubnd - s[k].lbnd + 1) * s[k].inc; + } + SCM_I_ARRAY_V (ra) = creator (scm_from_size_t (rlen), SCM_UNDEFINED); + + + scm_array_get_handle (ra, &h); + base = scm_array_handle_uniform_writable_elements (&h); + sz = scm_array_handle_uniform_element_size (&h); + scm_array_handle_release (&h); + + if (byte_len % sz) + SCM_MISC_ERROR ("byte length not a multiple of the unit size", SCM_EOL); + if (byte_len / sz != rlen) + SCM_MISC_ERROR ("byte length and dimensions do not match", SCM_EOL); + + memcpy (base, bytes, byte_len); + + if (1 == SCM_I_ARRAY_NDIM (ra) && 0 == SCM_I_ARRAY_BASE (ra)) + if (s->ubnd < s->lbnd || (0 == s->lbnd && 1 == s->inc)) + return SCM_I_ARRAY_V (ra); + return ra; +} +#undef FUNC_NAME + SCM_DEFINE (scm_make_array, "make-array", 1, 0, 1, (SCM fill, SCM bounds), "Create and return an array.") diff --git a/libguile/unif.h b/libguile/unif.h index a09bfc921..91d26c861 100644 --- a/libguile/unif.h +++ b/libguile/unif.h @@ -6,18 +6,19 @@ /* Copyright (C) 1995,1996,1997,1999,2000,2001, 2004, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ @@ -45,6 +46,9 @@ SCM_API SCM scm_array_p (SCM v, SCM prot); SCM_API SCM scm_typed_array_p (SCM v, SCM type); SCM_API SCM scm_make_array (SCM fill, SCM bounds); SCM_API SCM scm_make_typed_array (SCM type, SCM fill, SCM bounds); +SCM_API SCM scm_from_contiguous_typed_array (SCM type, SCM bounds, + const void *bytes, + size_t byte_len); SCM_API SCM scm_array_rank (SCM ra); SCM_API size_t scm_c_array_rank (SCM ra); SCM_API SCM scm_array_dimensions (SCM ra); diff --git a/libguile/validate.h b/libguile/validate.h index e05b7dd83..b48bec758 100644 --- a/libguile/validate.h +++ b/libguile/validate.h @@ -3,21 +3,22 @@ #ifndef SCM_VALIDATE_H #define SCM_VALIDATE_H -/* Copyright (C) 1999,2000,2001, 2002, 2004, 2006, 2007 Free Software Foundation, Inc. +/* Copyright (C) 1999,2000,2001, 2002, 2004, 2006, 2007, 2009 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ /* Written by Greg J. Badros , Dec-1999 */ @@ -150,6 +151,9 @@ cvar = scm_to_bool (flag); \ } while (0) +#define SCM_VALIDATE_BYTEVECTOR(_pos, _obj) \ + SCM_VALIDATE_SMOB ((_pos), (_obj), bytevector) + #define SCM_VALIDATE_CHAR(pos, scm) SCM_MAKE_VALIDATE_MSG (pos, scm, CHARP, "character") #define SCM_VALIDATE_CHAR_COPY(pos, scm, cvar) \ diff --git a/libguile/values.c b/libguile/values.c index e766edba1..81fdcf851 100644 --- a/libguile/values.c +++ b/libguile/values.c @@ -1,18 +1,19 @@ /* Copyright (C) 2000, 2001, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ #ifdef HAVE_CONFIG_H diff --git a/libguile/values.h b/libguile/values.h index f05ce9f8f..0750aecdc 100644 --- a/libguile/values.h +++ b/libguile/values.h @@ -6,18 +6,19 @@ /* Copyright (C) 2000,2001, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/variable.c b/libguile/variable.c index 6c39b30ac..a97444c0b 100644 --- a/libguile/variable.c +++ b/libguile/variable.c @@ -1,18 +1,19 @@ /* Copyright (C) 1995,1996,1997,1998,2000,2001, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/variable.h b/libguile/variable.h index 3f6398b9c..8faced4ec 100644 --- a/libguile/variable.h +++ b/libguile/variable.h @@ -6,18 +6,19 @@ /* Copyright (C) 1995,1996,2000,2001, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/vectors.c b/libguile/vectors.c index c01b3e3b6..255323f25 100644 --- a/libguile/vectors.c +++ b/libguile/vectors.c @@ -1,18 +1,19 @@ -/* Copyright (C) 1995,1996,1998,1999,2000,2001, 2006, 2008 Free Software Foundation, Inc. +/* Copyright (C) 1995,1996,1998,1999,2000,2001, 2006, 2008, 2009 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ @@ -30,6 +31,7 @@ #include "libguile/validate.h" #include "libguile/vectors.h" #include "libguile/unif.h" +#include "libguile/bytevectors.h" #include "libguile/ramap.h" #include "libguile/srfi-4.h" #include "libguile/strings.h" @@ -606,7 +608,7 @@ SCM_DEFINE (scm_vector_move_right_x, "vector-move-right!", 5, 0, 0, } #undef FUNC_NAME - + /* Generalized vectors. */ int @@ -615,7 +617,8 @@ scm_is_generalized_vector (SCM obj) return (scm_is_vector (obj) || scm_is_string (obj) || scm_is_bitvector (obj) - || scm_is_uniform_vector (obj)); + || scm_is_uniform_vector (obj) + || scm_is_bytevector (obj)); } SCM_DEFINE (scm_generalized_vector_p, "generalized-vector?", 1, 0, 0, @@ -647,6 +650,8 @@ scm_c_generalized_vector_length (SCM v) return scm_c_bitvector_length (v); else if (scm_is_uniform_vector (v)) return scm_c_uniform_vector_length (v); + else if (scm_is_bytevector (v)) + return scm_c_bytevector_length (v); else scm_wrong_type_arg_msg (NULL, 0, v, "generalized vector"); } @@ -671,6 +676,8 @@ scm_c_generalized_vector_ref (SCM v, size_t idx) return scm_c_bitvector_ref (v, idx); else if (scm_is_uniform_vector (v)) return scm_c_uniform_vector_ref (v, idx); + else if (scm_is_bytevector (v)) + return scm_from_uint8 (scm_c_bytevector_ref (v, idx)); else scm_wrong_type_arg_msg (NULL, 0, v, "generalized vector"); } @@ -696,6 +703,8 @@ scm_c_generalized_vector_set_x (SCM v, size_t idx, SCM val) scm_c_bitvector_set_x (v, idx, val); else if (scm_is_uniform_vector (v)) scm_c_uniform_vector_set_x (v, idx, val); + else if (scm_is_bytevector (v)) + scm_i_bytevector_generalized_set_x (v, idx, val); else scm_wrong_type_arg_msg (NULL, 0, v, "generalized vector"); } diff --git a/libguile/vectors.h b/libguile/vectors.h index 7a508c77b..7af38d822 100644 --- a/libguile/vectors.h +++ b/libguile/vectors.h @@ -6,18 +6,19 @@ /* Copyright (C) 1995,1996,1998,2000,2001,2002,2004,2005, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/version.c b/libguile/version.c index 6a665c53d..db1bc9f2e 100644 --- a/libguile/version.c +++ b/libguile/version.c @@ -1,18 +1,19 @@ /* Copyright (C) 1995,1996, 1999, 2000, 2001, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/version.h.in b/libguile/version.h.in index b565efd96..394bbdb86 100644 --- a/libguile/version.h.in +++ b/libguile/version.h.in @@ -6,18 +6,19 @@ /* Copyright (C) 1995,1996,1998,1999,2000,2001, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/vm-bootstrap.h b/libguile/vm-bootstrap.h index beecf0fc2..7ba1a93ba 100644 --- a/libguile/vm-bootstrap.h +++ b/libguile/vm-bootstrap.h @@ -1,48 +1,25 @@ /* Copyright (C) 2001 Free Software Foundation, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * 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 2, or (at your option) - * any later version. + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * 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 software; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307 USA - * - * As a special exception, the Free Software Foundation gives permission - * for additional uses of the text contained in its release of GUILE. - * - * The exception is that, if you link the GUILE library with other files - * to produce an executable, this does not by itself cause the - * resulting executable to be covered by the GNU General Public License. - * Your use of that executable is in no way restricted on account of - * linking the GUILE library code into it. - * - * This exception does not however invalidate any other reasons why - * the executable file might be covered by the GNU General Public License. - * - * This exception applies only to the code released by the - * Free Software Foundation under the name GUILE. If you copy - * code from other Free Software Foundation releases into a copy of - * GUILE, as the General Public License permits, the exception does - * not apply to the code that you add in this way. To avoid misleading - * anyone as to the status of such modified files, you must delete - * this exception notice from them. - * - * If you write modifications of your own for GUILE, it is your choice - * whether to permit this exception to apply to your modifications. - * If you do not wish that, delete this exception notice. */ + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ #ifndef _SCM_VM_BOOTSTRAP_H_ #define _SCM_VM_BOOTSTRAP_H_ -extern void scm_bootstrap_vm (void); +SCM_INTERNAL void scm_bootstrap_vm (void); #endif /* _SCM_VM_BOOTSTRAP_H_ */ diff --git a/libguile/vm-engine.c b/libguile/vm-engine.c index 58ed43db6..b0888c1ec 100644 --- a/libguile/vm-engine.c +++ b/libguile/vm-engine.c @@ -1,57 +1,34 @@ -/* Copyright (C) 2001 Free Software Foundation, Inc. - * - * 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 2, or (at your option) - * any later version. +/* Copyright (C) 2001, 2009 Free Software Foundation, Inc. * - * 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 software; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307 USA + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * As a special exception, the Free Software Foundation gives permission - * for additional uses of the text contained in its release of GUILE. + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * The exception is that, if you link the GUILE library with other files - * to produce an executable, this does not by itself cause the - * resulting executable to be covered by the GNU General Public License. - * Your use of that executable is in no way restricted on account of - * linking the GUILE library code into it. - * - * This exception does not however invalidate any other reasons why - * the executable file might be covered by the GNU General Public License. - * - * This exception applies only to the code released by the - * Free Software Foundation under the name GUILE. If you copy - * code from other Free Software Foundation releases into a copy of - * GUILE, as the General Public License permits, the exception does - * not apply to the code that you add in this way. To avoid misleading - * anyone as to the status of such modified files, you must delete - * this exception notice from them. - * - * If you write modifications of your own for GUILE, it is your choice - * whether to permit this exception to apply to your modifications. - * If you do not wish that, delete this exception notice. */ + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ /* This file is included in vm.c multiple times */ #if (VM_ENGINE == SCM_VM_REGULAR_ENGINE) #define VM_USE_HOOKS 0 /* Various hooks */ #define VM_USE_CLOCK 0 /* Bogoclock */ -#define VM_CHECK_EXTERNAL 1 /* Check external link */ #define VM_CHECK_OBJECT 1 /* Check object table */ +#define VM_CHECK_FREE_VARIABLES 1 /* Check free variable access */ #define VM_PUSH_DEBUG_FRAMES 0 /* Push frames onto the evaluator debug stack */ #elif (VM_ENGINE == SCM_VM_DEBUG_ENGINE) #define VM_USE_HOOKS 1 #define VM_USE_CLOCK 1 -#define VM_CHECK_EXTERNAL 1 #define VM_CHECK_OBJECT 1 +#define VM_CHECK_FREE_VARIABLES 1 #define VM_PUSH_DEBUG_FRAMES 1 #else #error unknown debug engine VM_ENGINE @@ -70,7 +47,8 @@ VM_NAME (struct scm_vm *vp, SCM program, SCM *argv, int nargs) /* Cache variables */ struct scm_objcode *bp = NULL; /* program base pointer */ - SCM external = SCM_EOL; /* external environment */ + SCM *free_vars = NULL; /* free variables */ + size_t free_vars_count = 0; /* length of FREE_VARS */ SCM *objects = NULL; /* constant objects */ size_t object_count = 0; /* length of OBJECTS */ SCM *stack_base = vp->stack_base; /* stack base address */ @@ -175,7 +153,7 @@ VM_NAME (struct scm_vm *vp, SCM program, SCM *argv, int nargs) vm_error_bad_instruction: err_msg = scm_from_locale_string ("VM: Bad instruction: ~A"); - finish_args = SCM_LIST1 (scm_from_uchar (ip[-1])); + finish_args = scm_list_1 (scm_from_uchar (ip[-1])); goto vm_error; vm_error_unbound: @@ -189,7 +167,7 @@ VM_NAME (struct scm_vm *vp, SCM program, SCM *argv, int nargs) vm_error_too_many_args: err_msg = scm_from_locale_string ("VM: Too many arguments"); - finish_args = SCM_LIST1 (scm_from_int (nargs)); + finish_args = scm_list_1 (scm_from_int (nargs)); goto vm_error; vm_error_wrong_num_args: @@ -202,8 +180,8 @@ VM_NAME (struct scm_vm *vp, SCM program, SCM *argv, int nargs) vm_error_wrong_type_apply: err_msg = scm_from_locale_string ("VM: Wrong type to apply: ~S " "[IP offset: ~a]"); - finish_args = SCM_LIST2 (program, - SCM_I_MAKINUM (ip - bp->base)); + finish_args = scm_list_2 (program, + SCM_I_MAKINUM (ip - bp->base)); goto vm_error; vm_error_stack_overflow: @@ -226,6 +204,12 @@ VM_NAME (struct scm_vm *vp, SCM program, SCM *argv, int nargs) /* shouldn't get here */ goto vm_error; + vm_error_not_a_bytevector: + SYNC_ALL (); + scm_wrong_type_arg_msg (FUNC_NAME, 1, finish_args, "bytevector"); + /* shouldn't get here */ + goto vm_error; + vm_error_no_values: err_msg = scm_from_locale_string ("VM: 0-valued return"); finish_args = SCM_EOL; @@ -236,8 +220,8 @@ VM_NAME (struct scm_vm *vp, SCM program, SCM *argv, int nargs) finish_args = SCM_EOL; goto vm_error; - vm_error_no_such_module: - err_msg = scm_from_locale_string ("VM: No such module: ~A"); + vm_error_bad_wide_string_length: + err_msg = scm_from_locale_string ("VM: Bad wide string length: ~S"); goto vm_error; #if VM_CHECK_IP @@ -247,13 +231,6 @@ VM_NAME (struct scm_vm *vp, SCM program, SCM *argv, int nargs) goto vm_error; #endif -#if VM_CHECK_EXTERNAL - vm_error_external: - err_msg = scm_from_locale_string ("VM: Invalid external access"); - finish_args = SCM_EOL; - goto vm_error; -#endif - #if VM_CHECK_OBJECT vm_error_object: err_msg = scm_from_locale_string ("VM: Invalid object table access"); @@ -261,10 +238,18 @@ VM_NAME (struct scm_vm *vp, SCM program, SCM *argv, int nargs) goto vm_error; #endif +#if VM_CHECK_FREE_VARIABLES + vm_error_free_variable: + err_msg = scm_from_locale_string ("VM: Invalid free variable access"); + finish_args = SCM_EOL; + goto vm_error; +#endif + vm_error: SYNC_ALL (); - scm_ithrow (sym_vm_error, SCM_LIST3 (sym_vm_run, err_msg, finish_args), 1); + scm_ithrow (sym_vm_error, scm_list_3 (sym_vm_run, err_msg, finish_args), + 1); } abort (); /* never reached */ @@ -272,8 +257,8 @@ VM_NAME (struct scm_vm *vp, SCM program, SCM *argv, int nargs) #undef VM_USE_HOOKS #undef VM_USE_CLOCK -#undef VM_CHECK_EXTERNAL #undef VM_CHECK_OBJECT +#undef VM_CHECK_FREE_VARIABLE #undef VM_PUSH_DEBUG_FRAMES /* diff --git a/libguile/vm-engine.h b/libguile/vm-engine.h index 6bb235401..240969c37 100644 --- a/libguile/vm-engine.h +++ b/libguile/vm-engine.h @@ -1,43 +1,20 @@ -/* Copyright (C) 2001 Free Software Foundation, Inc. - * - * 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 2, or (at your option) - * any later version. +/* Copyright (C) 2001, 2009 Free Software Foundation, Inc. * - * 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 software; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307 USA + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * As a special exception, the Free Software Foundation gives permission - * for additional uses of the text contained in its release of GUILE. + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * The exception is that, if you link the GUILE library with other files - * to produce an executable, this does not by itself cause the - * resulting executable to be covered by the GNU General Public License. - * Your use of that executable is in no way restricted on account of - * linking the GUILE library code into it. - * - * This exception does not however invalidate any other reasons why - * the executable file might be covered by the GNU General Public License. - * - * This exception applies only to the code released by the - * Free Software Foundation under the name GUILE. If you copy - * code from other Free Software Foundation releases into a copy of - * GUILE, as the General Public License permits, the exception does - * not apply to the code that you add in this way. To avoid misleading - * anyone as to the status of such modified files, you must delete - * this exception notice from them. - * - * If you write modifications of your own for GUILE, it is your choice - * whether to permit this exception to apply to your modifications. - * If you do not wish that, delete this exception notice. */ + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ /* This file is included in vm_engine.c */ @@ -77,13 +54,9 @@ #endif #endif #ifdef __i386__ -/* gcc on lenny actually crashes if we allocate these variables in registers. - hopefully this is the only one of these. */ -#if !(__GNUC__==4 && __GNUC_MINOR__==1 && __GNUC_PATCHLEVEL__==2) -#define IP_REG asm("%esi") -#define SP_REG asm("%edi") -#define FP_REG -#endif +/* too few registers! because of register allocation errors with various gcs, + just punt on explicit assignments on i386, hoping that the "register" + declaration will be sufficient. */ #endif #if defined(PPC) || defined(_POWER) || defined(_IBMR2) #define IP_REG asm("26") @@ -144,22 +117,36 @@ vp->fp = fp; \ } +/* FIXME */ +#define ASSERT_VARIABLE(x) \ + do { if (!SCM_VARIABLEP (x)) { SYNC_REGISTER (); abort(); } \ + } while (0) +#define ASSERT_BOUND_VARIABLE(x) \ + do { ASSERT_VARIABLE (x); \ + if (SCM_VARIABLE_REF (x) == SCM_UNDEFINED) \ + { SYNC_REGISTER (); abort(); } \ + } while (0) + #ifdef VM_ENABLE_PARANOID_ASSERTIONS #define CHECK_IP() \ do { if (ip < bp->base || ip - bp->base > bp->len) abort (); } while (0) +#define ASSERT_ALIGNED_PROCEDURE() \ + do { if ((scm_t_bits)bp % 8) abort (); } while (0) +#define ASSERT_BOUND(x) \ + do { if ((x) == SCM_UNDEFINED) { SYNC_REGISTER (); abort(); } \ + } while (0) #else #define CHECK_IP() +#define ASSERT_ALIGNED_PROCEDURE() +#define ASSERT_BOUND(x) #endif -/* Get a local copy of the program's "object table" (i.e. the vector of - external bindings that are referenced by the program), initialized by - `load-program'. */ -/* XXX: We could instead use the "simple vector macros", thus not having to - call `scm_vector_writable_elements ()' and the likes. */ +/* Cache the object table and free variables. */ #define CACHE_PROGRAM() \ { \ if (bp != SCM_PROGRAM_DATA (program)) { \ bp = SCM_PROGRAM_DATA (program); \ + ASSERT_ALIGNED_PROCEDURE (); \ if (SCM_I_IS_VECTOR (SCM_PROGRAM_OBJTABLE (program))) { \ objects = SCM_I_VECTOR_WELTS (SCM_PROGRAM_OBJTABLE (program)); \ object_count = SCM_I_VECTOR_LENGTH (SCM_PROGRAM_OBJTABLE (program)); \ @@ -168,6 +155,19 @@ object_count = 0; \ } \ } \ + { \ + SCM c = SCM_PROGRAM_FREE_VARIABLES (program); \ + if (SCM_I_IS_VECTOR (c)) \ + { \ + free_vars = SCM_I_VECTOR_WELTS (c); \ + free_vars_count = SCM_I_VECTOR_LENGTH (c); \ + } \ + else \ + { \ + free_vars = NULL; \ + free_vars_count = 0; \ + } \ + } \ } #define SYNC_BEFORE_GC() \ @@ -185,14 +185,6 @@ * Error check */ -#undef CHECK_EXTERNAL -#if VM_CHECK_EXTERNAL -#define CHECK_EXTERNAL(e) \ - do { if (SCM_UNLIKELY (!SCM_CONSP (e))) goto vm_error_external; } while (0) -#else -#define CHECK_EXTERNAL(e) -#endif - /* Accesses to a program's object table. */ #if VM_CHECK_OBJECT #define CHECK_OBJECT(_num) \ @@ -201,6 +193,13 @@ #define CHECK_OBJECT(_num) #endif +#if VM_CHECK_FREE_VARIABLES +#define CHECK_FREE_VARIABLE(_num) \ + do { if (SCM_UNLIKELY ((_num) >= free_vars_count)) goto vm_error_free_variable; } while (0) +#else +#define CHECK_FREE_VARIABLE(_num) +#endif + /* * Hooks @@ -337,6 +336,7 @@ do { \ #define FETCH() (*ip++) #define FETCH_LENGTH(len) do { len=*ip++; len<<=8; len+=*ip++; len<<=8; len+=*ip++; } while (0) +#define FETCH_WIDTH(width) do { width=*ip++; } while (0) #undef CLOCK #if VM_USE_CLOCK @@ -399,7 +399,7 @@ do { \ /* New registers */ \ fp = sp - bp->nargs + 1; \ data = SCM_FRAME_DATA_ADDRESS (fp); \ - sp = data + 3; \ + sp = data + 2; \ CHECK_OVERFLOW (); \ stack_base = sp; \ ip = bp->base; \ @@ -409,23 +409,11 @@ do { \ data[-i] = SCM_UNDEFINED; \ \ /* Set frame data */ \ - data[3] = (SCM)ra; \ - data[2] = 0x0; \ - data[1] = (SCM)dl; \ - \ - /* Postpone initializing external vars, \ - because if the CONS causes a GC, we \ - want the stack marker to see the data \ - array formatted as expected. */ \ - data[0] = SCM_UNDEFINED; \ - external = SCM_PROGRAM_EXTERNALS (fp[-1]); \ - for (i = 0; i < bp->nexts; i++) \ - CONS (external, SCM_UNDEFINED, external); \ - data[0] = external; \ + data[2] = (SCM)ra; \ + data[1] = 0x0; \ + data[0] = (SCM)dl; \ } -#define CACHE_EXTERNAL() external = fp[bp->nargs + bp->nlocs] - /* Local Variables: c-file-style: "gnu" diff --git a/libguile/vm-expand.h b/libguile/vm-expand.h index 7ad2b9da8..787223d07 100644 --- a/libguile/vm-expand.h +++ b/libguile/vm-expand.h @@ -1,43 +1,20 @@ /* Copyright (C) 2001 Free Software Foundation, Inc. - * - * 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 2, 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 software; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307 USA + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * As a special exception, the Free Software Foundation gives permission - * for additional uses of the text contained in its release of GUILE. + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * The exception is that, if you link the GUILE library with other files - * to produce an executable, this does not by itself cause the - * resulting executable to be covered by the GNU General Public License. - * Your use of that executable is in no way restricted on account of - * linking the GUILE library code into it. - * - * This exception does not however invalidate any other reasons why - * the executable file might be covered by the GNU General Public License. - * - * This exception applies only to the code released by the - * Free Software Foundation under the name GUILE. If you copy - * code from other Free Software Foundation releases into a copy of - * GUILE, as the General Public License permits, the exception does - * not apply to the code that you add in this way. To avoid misleading - * anyone as to the status of such modified files, you must delete - * this exception notice from them. - * - * If you write modifications of your own for GUILE, it is your choice - * whether to permit this exception to apply to your modifications. - * If you do not wish that, delete this exception notice. */ + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ #ifndef VM_LABEL #define VM_LABEL(tag) l_##tag diff --git a/libguile/vm-i-loader.c b/libguile/vm-i-loader.c index bba4f4b9c..e242ef9bf 100644 --- a/libguile/vm-i-loader.c +++ b/libguile/vm-i-loader.c @@ -1,60 +1,26 @@ /* Copyright (C) 2001,2008,2009 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ +/* FIXME! Need to check that the fetch is within the current program */ /* This file is included in vm_engine.c */ -VM_DEFINE_LOADER (59, load_unsigned_integer, "load-unsigned-integer") -{ - size_t len; - - FETCH_LENGTH (len); - if (SCM_LIKELY (len <= 4)) - { - unsigned int val = 0; - while (len-- > 0) - val = (val << 8U) + FETCH (); - SYNC_REGISTER (); - PUSH (scm_from_uint (val)); - NEXT; - } - else - SCM_MISC_ERROR ("load-unsigned-integer: not implemented yet", SCM_EOL); -} - -VM_DEFINE_LOADER (60, load_integer, "load-integer") -{ - size_t len; - - FETCH_LENGTH (len); - if (SCM_LIKELY (len <= 4)) - { - int val = 0; - while (len-- > 0) - val = (val << 8) + FETCH (); - SYNC_REGISTER (); - PUSH (scm_from_int (val)); - NEXT; - } - else - SCM_MISC_ERROR ("load-integer: not implemented yet", SCM_EOL); -} - -VM_DEFINE_LOADER (61, load_number, "load-number") +VM_DEFINE_LOADER (82, load_number, "load-number") { size_t len; @@ -67,38 +33,31 @@ VM_DEFINE_LOADER (61, load_number, "load-number") NEXT; } -VM_DEFINE_LOADER (62, load_string, "load-string") +VM_DEFINE_LOADER (83, load_string, "load-string") { size_t len; + char *buf; + FETCH_LENGTH (len); SYNC_REGISTER (); - PUSH (scm_from_locale_stringn ((char *)ip, len)); - /* Was: scm_makfromstr (ip, len, 0) */ + PUSH (scm_i_make_string (len, &buf)); + memcpy (buf, (char *) ip, len); ip += len; NEXT; } -VM_DEFINE_LOADER (63, load_symbol, "load-symbol") +VM_DEFINE_LOADER (84, load_symbol, "load-symbol") { size_t len; FETCH_LENGTH (len); SYNC_REGISTER (); - PUSH (scm_from_locale_symboln ((char *)ip, len)); + /* FIXME: should be scm_from_latin1_symboln */ + PUSH (scm_from_locale_symboln ((const char*)ip, len)); ip += len; NEXT; } -VM_DEFINE_LOADER (64, load_keyword, "load-keyword") -{ - size_t len; - FETCH_LENGTH (len); - SYNC_REGISTER (); - PUSH (scm_from_locale_keywordn ((char *)ip, len)); - ip += len; - NEXT; -} - -VM_DEFINE_LOADER (65, load_program, "load-program") +VM_DEFINE_LOADER (86, load_program, "load-program") { scm_t_uint32 len; SCM objs, objcode; @@ -112,56 +71,50 @@ VM_DEFINE_LOADER (65, load_program, "load-program") objcode = scm_c_make_objcode_slice (SCM_PROGRAM_OBJCODE (fp[-1]), ip); len = sizeof (struct scm_objcode) + SCM_OBJCODE_TOTAL_LEN (objcode); - PUSH (scm_make_program (objcode, objs, SCM_EOL)); + PUSH (scm_make_program (objcode, objs, SCM_BOOL_F)); ip += len; NEXT; } -VM_DEFINE_INSTRUCTION (66, link_now, "link-now", 0, 1, 1) +VM_DEFINE_INSTRUCTION (87, link_now, "link-now", 0, 1, 1) { SCM what; POP (what); SYNC_REGISTER (); - if (SCM_LIKELY (SCM_SYMBOLP (what))) - { - PUSH (scm_lookup (what)); /* might longjmp */ - } - else - { - SCM mod; - /* compilation of @ or @@ - `what' is a three-element list: (MODNAME SYM INTERFACE?) - INTERFACE? is #t if we compiled @ or #f if we compiled @@ - */ - mod = scm_resolve_module (SCM_CAR (what)); - if (scm_is_true (SCM_CADDR (what))) - mod = scm_module_public_interface (mod); - if (SCM_FALSEP (mod)) - { - finish_args = SCM_LIST1 (SCM_CAR (what)); - goto vm_error_no_such_module; - } - /* might longjmp */ - PUSH (scm_module_lookup (mod, SCM_CADR (what))); - } - + PUSH (resolve_variable (what, scm_current_module ())); NEXT; } -VM_DEFINE_LOADER (67, define, "define") +VM_DEFINE_LOADER (89, load_array, "load-array") { - SCM sym; + SCM type, shape; size_t len; + FETCH_LENGTH (len); + POP (shape); + POP (type); + SYNC_REGISTER (); + PUSH (scm_from_contiguous_typed_array (type, shape, ip, len)); + ip += len; + NEXT; +} + +VM_DEFINE_LOADER (90, load_wide_string, "load-wide-string") +{ + size_t len; + scm_t_wchar *wbuf; FETCH_LENGTH (len); - SYNC_REGISTER (); - sym = scm_from_locale_symboln ((char *)ip, len); - ip += len; + if (SCM_UNLIKELY (len % 4)) + { finish_args = scm_list_1 (scm_from_size_t (len)); + goto vm_error_bad_wide_string_length; + } SYNC_REGISTER (); - PUSH (scm_sym2var (sym, scm_current_module_lookup_closure (), SCM_BOOL_T)); + PUSH (scm_i_make_wide_string (len / 4, &wbuf)); + memcpy ((char *) wbuf, (char *) ip, len); + ip += len; NEXT; } @@ -170,7 +123,7 @@ VM_DEFINE_LOADER (67, define, "define") "start from top of buffer and renumber 'VM_DEFINE_FOO (\n' sequences" (interactive "") (save-excursion - (let ((counter 59)) (goto-char (point-min)) + (let ((counter 79)) (goto-char (point-min)) (while (re-search-forward "^VM_DEFINE_[^ ]+ (\\([^,]+\\)," (point-max) t) (replace-match (number-to-string (setq counter (1+ counter))) diff --git a/libguile/vm-i-scheme.c b/libguile/vm-i-scheme.c index 4af60265e..0cace147d 100644 --- a/libguile/vm-i-scheme.c +++ b/libguile/vm-i-scheme.c @@ -1,43 +1,20 @@ -/* Copyright (C) 2001 Free Software Foundation, Inc. - * - * 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 2, or (at your option) - * any later version. +/* Copyright (C) 2001, 2009 Free Software Foundation, Inc. * - * 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 software; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307 USA + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * As a special exception, the Free Software Foundation gives permission - * for additional uses of the text contained in its release of GUILE. + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * The exception is that, if you link the GUILE library with other files - * to produce an executable, this does not by itself cause the - * resulting executable to be covered by the GNU General Public License. - * Your use of that executable is in no way restricted on account of - * linking the GUILE library code into it. - * - * This exception does not however invalidate any other reasons why - * the executable file might be covered by the GNU General Public License. - * - * This exception applies only to the code released by the - * Free Software Foundation under the name GUILE. If you copy - * code from other Free Software Foundation releases into a copy of - * GUILE, as the General Public License permits, the exception does - * not apply to the code that you add in this way. To avoid misleading - * anyone as to the status of such modified files, you must delete - * this exception notice from them. - * - * If you write modifications of your own for GUILE, it is your choice - * whether to permit this exception to apply to your modifications. - * If you do not wish that, delete this exception notice. */ + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ /* This file is included in vm_engine.c */ @@ -52,43 +29,43 @@ #define RETURN(x) do { *sp = x; NEXT; } while (0) -VM_DEFINE_FUNCTION (80, not, "not", 1) +VM_DEFINE_FUNCTION (100, not, "not", 1) { ARGS1 (x); RETURN (SCM_BOOL (SCM_FALSEP (x))); } -VM_DEFINE_FUNCTION (81, not_not, "not-not", 1) +VM_DEFINE_FUNCTION (101, not_not, "not-not", 1) { ARGS1 (x); RETURN (SCM_BOOL (!SCM_FALSEP (x))); } -VM_DEFINE_FUNCTION (82, eq, "eq?", 2) +VM_DEFINE_FUNCTION (102, eq, "eq?", 2) { ARGS2 (x, y); RETURN (SCM_BOOL (SCM_EQ_P (x, y))); } -VM_DEFINE_FUNCTION (83, not_eq, "not-eq?", 2) +VM_DEFINE_FUNCTION (103, not_eq, "not-eq?", 2) { ARGS2 (x, y); RETURN (SCM_BOOL (!SCM_EQ_P (x, y))); } -VM_DEFINE_FUNCTION (84, nullp, "null?", 1) +VM_DEFINE_FUNCTION (104, nullp, "null?", 1) { ARGS1 (x); RETURN (SCM_BOOL (SCM_NULLP (x))); } -VM_DEFINE_FUNCTION (85, not_nullp, "not-null?", 1) +VM_DEFINE_FUNCTION (105, not_nullp, "not-null?", 1) { ARGS1 (x); RETURN (SCM_BOOL (!SCM_NULLP (x))); } -VM_DEFINE_FUNCTION (86, eqv, "eqv?", 2) +VM_DEFINE_FUNCTION (106, eqv, "eqv?", 2) { ARGS2 (x, y); if (SCM_EQ_P (x, y)) @@ -99,7 +76,7 @@ VM_DEFINE_FUNCTION (86, eqv, "eqv?", 2) RETURN (scm_eqv_p (x, y)); } -VM_DEFINE_FUNCTION (87, equal, "equal?", 2) +VM_DEFINE_FUNCTION (107, equal, "equal?", 2) { ARGS2 (x, y); if (SCM_EQ_P (x, y)) @@ -110,13 +87,13 @@ VM_DEFINE_FUNCTION (87, equal, "equal?", 2) RETURN (scm_equal_p (x, y)); } -VM_DEFINE_FUNCTION (88, pairp, "pair?", 1) +VM_DEFINE_FUNCTION (108, pairp, "pair?", 1) { ARGS1 (x); RETURN (SCM_BOOL (SCM_CONSP (x))); } -VM_DEFINE_FUNCTION (89, listp, "list?", 1) +VM_DEFINE_FUNCTION (109, listp, "list?", 1) { ARGS1 (x); RETURN (SCM_BOOL (scm_ilength (x) >= 0)); @@ -127,7 +104,7 @@ VM_DEFINE_FUNCTION (89, listp, "list?", 1) * Basic data */ -VM_DEFINE_FUNCTION (90, cons, "cons", 2) +VM_DEFINE_FUNCTION (110, cons, "cons", 2) { ARGS2 (x, y); CONS (x, x, y); @@ -140,34 +117,38 @@ VM_DEFINE_FUNCTION (90, cons, "cons", 2) goto vm_error_not_a_pair; \ } -VM_DEFINE_FUNCTION (91, car, "car", 1) +VM_DEFINE_FUNCTION (111, car, "car", 1) { ARGS1 (x); VM_VALIDATE_CONS (x); RETURN (SCM_CAR (x)); } -VM_DEFINE_FUNCTION (92, cdr, "cdr", 1) +VM_DEFINE_FUNCTION (112, cdr, "cdr", 1) { ARGS1 (x); VM_VALIDATE_CONS (x); RETURN (SCM_CDR (x)); } -VM_DEFINE_FUNCTION (93, set_car, "set-car!", 2) +VM_DEFINE_INSTRUCTION (113, set_car, "set-car!", 0, 2, 0) { - ARGS2 (x, y); + SCM x, y; + POP (y); + POP (x); VM_VALIDATE_CONS (x); SCM_SETCAR (x, y); - RETURN (SCM_UNSPECIFIED); + NEXT; } -VM_DEFINE_FUNCTION (94, set_cdr, "set-cdr!", 2) +VM_DEFINE_INSTRUCTION (114, set_cdr, "set-cdr!", 0, 2, 0) { - ARGS2 (x, y); + SCM x, y; + POP (y); + POP (x); VM_VALIDATE_CONS (x); SCM_SETCDR (x, y); - RETURN (SCM_UNSPECIFIED); + NEXT; } @@ -185,27 +166,27 @@ VM_DEFINE_FUNCTION (94, set_cdr, "set-cdr!", 2) RETURN (srel (x, y)); \ } -VM_DEFINE_FUNCTION (95, ee, "ee?", 2) +VM_DEFINE_FUNCTION (115, ee, "ee?", 2) { REL (==, scm_num_eq_p); } -VM_DEFINE_FUNCTION (96, lt, "lt?", 2) +VM_DEFINE_FUNCTION (116, lt, "lt?", 2) { REL (<, scm_less_p); } -VM_DEFINE_FUNCTION (97, le, "le?", 2) +VM_DEFINE_FUNCTION (117, le, "le?", 2) { REL (<=, scm_leq_p); } -VM_DEFINE_FUNCTION (98, gt, "gt?", 2) +VM_DEFINE_FUNCTION (118, gt, "gt?", 2) { REL (>, scm_gr_p); } -VM_DEFINE_FUNCTION (99, ge, "ge?", 2) +VM_DEFINE_FUNCTION (119, ge, "ge?", 2) { REL (>=, scm_geq_p); } @@ -221,7 +202,7 @@ VM_DEFINE_FUNCTION (99, ge, "ge?", 2) ARGS2 (x, y); \ if (SCM_I_INUMP (x) && SCM_I_INUMP (y)) \ { \ - scm_t_bits n = SCM_I_INUM (x) CFUNC SCM_I_INUM (y);\ + scm_t_int64 n = SCM_I_INUM (x) CFUNC SCM_I_INUM (y);\ if (SCM_FIXABLE (n)) \ RETURN (SCM_I_MAKINUM (n)); \ } \ @@ -229,45 +210,71 @@ VM_DEFINE_FUNCTION (99, ge, "ge?", 2) RETURN (SFUNC (x, y)); \ } -VM_DEFINE_FUNCTION (100, add, "add", 2) +VM_DEFINE_FUNCTION (120, add, "add", 2) { FUNC2 (+, scm_sum); } -VM_DEFINE_FUNCTION (101, sub, "sub", 2) +VM_DEFINE_FUNCTION (167, add1, "add1", 1) +{ + ARGS1 (x); + if (SCM_I_INUMP (x)) + { + scm_t_int64 n = SCM_I_INUM (x) + 1; + if (SCM_FIXABLE (n)) + RETURN (SCM_I_MAKINUM (n)); + } + SYNC_REGISTER (); + RETURN (scm_sum (x, SCM_I_MAKINUM (1))); +} + +VM_DEFINE_FUNCTION (121, sub, "sub", 2) { FUNC2 (-, scm_difference); } -VM_DEFINE_FUNCTION (102, mul, "mul", 2) +VM_DEFINE_FUNCTION (168, sub1, "sub1", 1) +{ + ARGS1 (x); + if (SCM_I_INUMP (x)) + { + scm_t_int64 n = SCM_I_INUM (x) - 1; + if (SCM_FIXABLE (n)) + RETURN (SCM_I_MAKINUM (n)); + } + SYNC_REGISTER (); + RETURN (scm_difference (x, SCM_I_MAKINUM (1))); +} + +VM_DEFINE_FUNCTION (122, mul, "mul", 2) { ARGS2 (x, y); SYNC_REGISTER (); RETURN (scm_product (x, y)); } -VM_DEFINE_FUNCTION (103, div, "div", 2) +VM_DEFINE_FUNCTION (123, div, "div", 2) { ARGS2 (x, y); SYNC_REGISTER (); RETURN (scm_divide (x, y)); } -VM_DEFINE_FUNCTION (104, quo, "quo", 2) +VM_DEFINE_FUNCTION (124, quo, "quo", 2) { ARGS2 (x, y); SYNC_REGISTER (); RETURN (scm_quotient (x, y)); } -VM_DEFINE_FUNCTION (105, rem, "rem", 2) +VM_DEFINE_FUNCTION (125, rem, "rem", 2) { ARGS2 (x, y); SYNC_REGISTER (); RETURN (scm_remainder (x, y)); } -VM_DEFINE_FUNCTION (106, mod, "mod", 2) +VM_DEFINE_FUNCTION (126, mod, "mod", 2) { ARGS2 (x, y); SYNC_REGISTER (); @@ -278,7 +285,7 @@ VM_DEFINE_FUNCTION (106, mod, "mod", 2) /* * GOOPS support */ -VM_DEFINE_FUNCTION (107, slot_ref, "slot-ref", 2) +VM_DEFINE_FUNCTION (127, slot_ref, "slot-ref", 2) { size_t slot; ARGS2 (instance, idx); @@ -286,21 +293,277 @@ VM_DEFINE_FUNCTION (107, slot_ref, "slot-ref", 2) RETURN (SCM_PACK (SCM_STRUCT_DATA (instance) [slot])); } -VM_DEFINE_FUNCTION (108, slot_set, "slot-set", 3) +VM_DEFINE_INSTRUCTION (128, slot_set, "slot-set", 0, 3, 0) { + SCM instance, idx, val; size_t slot; - ARGS3 (instance, idx, val); + POP (val); + POP (idx); + POP (instance); slot = SCM_I_INUM (idx); SCM_STRUCT_DATA (instance) [slot] = SCM_UNPACK (val); - RETURN (SCM_UNSPECIFIED); + NEXT; } +VM_DEFINE_FUNCTION (129, vector_ref, "vector-ref", 2) +{ + long i = 0; + ARGS2 (vect, idx); + if (SCM_LIKELY (SCM_I_IS_VECTOR (vect) + && SCM_I_INUMP (idx) + && ((i = SCM_I_INUM (idx)) >= 0) + && i < SCM_I_VECTOR_LENGTH (vect))) + RETURN (SCM_I_VECTOR_ELTS (vect)[i]); + else + { + SYNC_REGISTER (); + RETURN (scm_vector_ref (vect, idx)); + } +} + +VM_DEFINE_INSTRUCTION (130, vector_set, "vector-set", 0, 3, 0) +{ + long i = 0; + SCM vect, idx, val; + POP (val); POP (idx); POP (vect); + if (SCM_LIKELY (SCM_I_IS_VECTOR (vect) + && SCM_I_INUMP (idx) + && ((i = SCM_I_INUM (idx)) >= 0) + && i < SCM_I_VECTOR_LENGTH (vect))) + SCM_I_VECTOR_WELTS (vect)[i] = val; + else + { + SYNC_REGISTER (); + scm_vector_set_x (vect, idx, val); + } + NEXT; +} + +#define VM_VALIDATE_BYTEVECTOR(x) \ + if (SCM_UNLIKELY (!SCM_BYTEVECTOR_P (x))) \ + { finish_args = x; \ + goto vm_error_not_a_bytevector; \ + } + +#define BV_REF_WITH_ENDIANNESS(stem, fn_stem) \ +{ \ + SCM endianness; \ + POP (endianness); \ + if (scm_is_eq (endianness, scm_i_native_endianness)) \ + goto VM_LABEL (bv_##stem##_native_ref); \ + { \ + ARGS2 (bv, idx); \ + RETURN (scm_bytevector_##fn_stem##_ref (bv, idx, endianness)); \ + } \ +} + +VM_DEFINE_FUNCTION (131, bv_u16_ref, "bv-u16-ref", 3) +BV_REF_WITH_ENDIANNESS (u16, u16) +VM_DEFINE_FUNCTION (132, bv_s16_ref, "bv-s16-ref", 3) +BV_REF_WITH_ENDIANNESS (s16, s16) +VM_DEFINE_FUNCTION (133, bv_u32_ref, "bv-u32-ref", 3) +BV_REF_WITH_ENDIANNESS (u32, u32) +VM_DEFINE_FUNCTION (134, bv_s32_ref, "bv-s32-ref", 3) +BV_REF_WITH_ENDIANNESS (s32, s32) +VM_DEFINE_FUNCTION (135, bv_u64_ref, "bv-u64-ref", 3) +BV_REF_WITH_ENDIANNESS (u64, u64) +VM_DEFINE_FUNCTION (136, bv_s64_ref, "bv-s64-ref", 3) +BV_REF_WITH_ENDIANNESS (s64, s64) +VM_DEFINE_FUNCTION (137, bv_f32_ref, "bv-f32-ref", 3) +BV_REF_WITH_ENDIANNESS (f32, ieee_single) +VM_DEFINE_FUNCTION (138, bv_f64_ref, "bv-f64-ref", 3) +BV_REF_WITH_ENDIANNESS (f64, ieee_double) + +#undef BV_REF_WITH_ENDIANNESS + +#define BV_FIXABLE_INT_REF(stem, fn_stem, type, size) \ +{ \ + long i = 0; \ + ARGS2 (bv, idx); \ + VM_VALIDATE_BYTEVECTOR (bv); \ + if (SCM_LIKELY (SCM_I_INUMP (idx) \ + && ((i = SCM_I_INUM (idx)) >= 0) \ + && (i + size <= SCM_BYTEVECTOR_LENGTH (bv)) \ + && (i % size == 0))) \ + RETURN (SCM_I_MAKINUM (*(scm_t_##type*) \ + (SCM_BYTEVECTOR_CONTENTS (bv) + i))); \ + else \ + RETURN (scm_bytevector_##fn_stem##_ref (bv, idx)); \ +} + +#define BV_INT_REF(stem, type, size) \ +{ \ + long i = 0; \ + ARGS2 (bv, idx); \ + VM_VALIDATE_BYTEVECTOR (bv); \ + if (SCM_LIKELY (SCM_I_INUMP (idx) \ + && ((i = SCM_I_INUM (idx)) >= 0) \ + && (i + size <= SCM_BYTEVECTOR_LENGTH (bv)) \ + && (i % size == 0))) \ + { scm_t_##type x = (*(scm_t_##type*)(SCM_BYTEVECTOR_CONTENTS (bv) + i)); \ + if (SCM_FIXABLE (x)) \ + RETURN (SCM_I_MAKINUM (x)); \ + else \ + RETURN (scm_from_##type (x)); \ + } \ + else \ + RETURN (scm_bytevector_##stem##_native_ref (bv, idx)); \ +} + +#define BV_FLOAT_REF(stem, fn_stem, type, size) \ +{ \ + long i = 0; \ + ARGS2 (bv, idx); \ + VM_VALIDATE_BYTEVECTOR (bv); \ + if (SCM_LIKELY (SCM_I_INUMP (idx) \ + && ((i = SCM_I_INUM (idx)) >= 0) \ + && (i + size <= SCM_BYTEVECTOR_LENGTH (bv)) \ + && (i % size == 0))) \ + RETURN (scm_from_double ((*(type*)(SCM_BYTEVECTOR_CONTENTS (bv) + i)))); \ + else \ + RETURN (scm_bytevector_##fn_stem##_native_ref (bv, idx)); \ +} + +VM_DEFINE_FUNCTION (139, bv_u8_ref, "bv-u8-ref", 2) +BV_FIXABLE_INT_REF (u8, u8, uint8, 1) +VM_DEFINE_FUNCTION (140, bv_s8_ref, "bv-s8-ref", 2) +BV_FIXABLE_INT_REF (s8, s8, int8, 1) +VM_DEFINE_FUNCTION (141, bv_u16_native_ref, "bv-u16-native-ref", 2) +BV_FIXABLE_INT_REF (u16, u16_native, uint16, 2) +VM_DEFINE_FUNCTION (142, bv_s16_native_ref, "bv-s16-native-ref", 2) +BV_FIXABLE_INT_REF (s16, s16_native, int16, 2) +VM_DEFINE_FUNCTION (143, bv_u32_native_ref, "bv-u32-native-ref", 2) +/* FIXME: u32 is always a fixnum on 64-bit builds */ +BV_INT_REF (u32, uint32, 4) +VM_DEFINE_FUNCTION (144, bv_s32_native_ref, "bv-s32-native-ref", 2) +BV_INT_REF (s32, int32, 4) +VM_DEFINE_FUNCTION (145, bv_u64_native_ref, "bv-u64-native-ref", 2) +BV_INT_REF (u64, uint64, 8) +VM_DEFINE_FUNCTION (146, bv_s64_native_ref, "bv-s64-native-ref", 2) +BV_INT_REF (s64, int64, 8) +VM_DEFINE_FUNCTION (147, bv_f32_native_ref, "bv-f32-native-ref", 2) +BV_FLOAT_REF (f32, ieee_single, float, 4) +VM_DEFINE_FUNCTION (148, bv_f64_native_ref, "bv-f64-native-ref", 2) +BV_FLOAT_REF (f64, ieee_double, double, 8) + +#undef BV_FIXABLE_INT_REF +#undef BV_INT_REF +#undef BV_FLOAT_REF + + + +#define BV_SET_WITH_ENDIANNESS(stem, fn_stem) \ +{ \ + SCM endianness; \ + POP (endianness); \ + if (scm_is_eq (endianness, scm_i_native_endianness)) \ + goto VM_LABEL (bv_##stem##_native_set); \ + { \ + SCM bv, idx, val; POP (val); POP (idx); POP (bv); \ + scm_bytevector_##fn_stem##_set_x (bv, idx, val, endianness); \ + NEXT; \ + } \ +} + +VM_DEFINE_INSTRUCTION (149, bv_u16_set, "bv-u16-set", 0, 4, 0) +BV_SET_WITH_ENDIANNESS (u16, u16) +VM_DEFINE_INSTRUCTION (150, bv_s16_set, "bv-s16-set", 0, 4, 0) +BV_SET_WITH_ENDIANNESS (s16, s16) +VM_DEFINE_INSTRUCTION (151, bv_u32_set, "bv-u32-set", 0, 4, 0) +BV_SET_WITH_ENDIANNESS (u32, u32) +VM_DEFINE_INSTRUCTION (152, bv_s32_set, "bv-s32-set", 0, 4, 0) +BV_SET_WITH_ENDIANNESS (s32, s32) +VM_DEFINE_INSTRUCTION (153, bv_u64_set, "bv-u64-set", 0, 4, 0) +BV_SET_WITH_ENDIANNESS (u64, u64) +VM_DEFINE_INSTRUCTION (154, bv_s64_set, "bv-s64-set", 0, 4, 0) +BV_SET_WITH_ENDIANNESS (s64, s64) +VM_DEFINE_INSTRUCTION (155, bv_f32_set, "bv-f32-set", 0, 4, 0) +BV_SET_WITH_ENDIANNESS (f32, ieee_single) +VM_DEFINE_INSTRUCTION (156, bv_f64_set, "bv-f64-set", 0, 4, 0) +BV_SET_WITH_ENDIANNESS (f64, ieee_double) + +#undef BV_SET_WITH_ENDIANNESS + +#define BV_FIXABLE_INT_SET(stem, fn_stem, type, min, max, size) \ +{ \ + long i = 0, j = 0; \ + SCM bv, idx, val; POP (val); POP (idx); POP (bv); \ + VM_VALIDATE_BYTEVECTOR (bv); \ + if (SCM_LIKELY (SCM_I_INUMP (idx) \ + && ((i = SCM_I_INUM (idx)) >= 0) \ + && (i + size <= SCM_BYTEVECTOR_LENGTH (bv)) \ + && (i % size == 0) \ + && (SCM_I_INUMP (val)) \ + && ((j = SCM_I_INUM (val)) >= min) \ + && (j <= max))) \ + *(scm_t_##type*) (SCM_BYTEVECTOR_CONTENTS (bv) + i) = (scm_t_##type)j; \ + else \ + scm_bytevector_##fn_stem##_set_x (bv, idx, val); \ + NEXT; \ +} + +#define BV_INT_SET(stem, type, size) \ +{ \ + long i = 0; \ + SCM bv, idx, val; POP (val); POP (idx); POP (bv); \ + VM_VALIDATE_BYTEVECTOR (bv); \ + if (SCM_LIKELY (SCM_I_INUMP (idx) \ + && ((i = SCM_I_INUM (idx)) >= 0) \ + && (i + size <= SCM_BYTEVECTOR_LENGTH (bv)) \ + && (i % size == 0))) \ + *(scm_t_##type*) (SCM_BYTEVECTOR_CONTENTS (bv) + i) = scm_to_##type (val); \ + else \ + scm_bytevector_##stem##_native_set_x (bv, idx, val); \ + NEXT; \ +} + +#define BV_FLOAT_SET(stem, fn_stem, type, size) \ +{ \ + long i = 0; \ + SCM bv, idx, val; POP (val); POP (idx); POP (bv); \ + VM_VALIDATE_BYTEVECTOR (bv); \ + if (SCM_LIKELY (SCM_I_INUMP (idx) \ + && ((i = SCM_I_INUM (idx)) >= 0) \ + && (i + size <= SCM_BYTEVECTOR_LENGTH (bv)) \ + && (i % size == 0))) \ + *(type*) (SCM_BYTEVECTOR_CONTENTS (bv) + i) = scm_to_double (val); \ + else \ + scm_bytevector_##fn_stem##_native_set_x (bv, idx, val); \ + NEXT; \ +} + +VM_DEFINE_INSTRUCTION (157, bv_u8_set, "bv-u8-set", 0, 3, 0) +BV_FIXABLE_INT_SET (u8, u8, uint8, 0, SCM_T_UINT8_MAX, 1) +VM_DEFINE_INSTRUCTION (158, bv_s8_set, "bv-s8-set", 0, 3, 0) +BV_FIXABLE_INT_SET (s8, s8, int8, SCM_T_INT8_MIN, SCM_T_INT8_MAX, 1) +VM_DEFINE_INSTRUCTION (159, bv_u16_native_set, "bv-u16-native-set", 0, 3, 0) +BV_FIXABLE_INT_SET (u16, u16_native, uint16, 0, SCM_T_UINT16_MAX, 2) +VM_DEFINE_INSTRUCTION (160, bv_s16_native_set, "bv-s16-native-set", 0, 3, 0) +BV_FIXABLE_INT_SET (s16, s16_native, int16, SCM_T_INT16_MIN, SCM_T_INT16_MAX, 2) +VM_DEFINE_INSTRUCTION (161, bv_u32_native_set, "bv-u32-native-set", 0, 3, 0) +/* FIXME: u32 is always a fixnum on 64-bit builds */ +BV_INT_SET (u32, uint32, 4) +VM_DEFINE_INSTRUCTION (162, bv_s32_native_set, "bv-s32-native-set", 0, 3, 0) +BV_INT_SET (s32, int32, 4) +VM_DEFINE_INSTRUCTION (163, bv_u64_native_set, "bv-u64-native-set", 0, 3, 0) +BV_INT_SET (u64, uint64, 8) +VM_DEFINE_INSTRUCTION (164, bv_s64_native_set, "bv-s64-native-set", 0, 3, 0) +BV_INT_SET (s64, int64, 8) +VM_DEFINE_INSTRUCTION (165, bv_f32_native_set, "bv-f32-native-set", 0, 3, 0) +BV_FLOAT_SET (f32, ieee_single, float, 4) +VM_DEFINE_INSTRUCTION (166, bv_f64_native_set, "bv-f64-native-set", 0, 3, 0) +BV_FLOAT_SET (f64, ieee_double, double, 8) + +#undef BV_FIXABLE_INT_SET +#undef BV_INT_SET +#undef BV_FLOAT_SET + /* (defun renumber-ops () "start from top of buffer and renumber 'VM_DEFINE_FOO (\n' sequences" (interactive "") (save-excursion - (let ((counter 79)) (goto-char (point-min)) + (let ((counter 99)) (goto-char (point-min)) (while (re-search-forward "^VM_DEFINE_[^ ]+ (\\([^,]+\\)," (point-max) t) (replace-match (number-to-string (setq counter (1+ counter))) diff --git a/libguile/vm-i-system.c b/libguile/vm-i-system.c index c1ea1c161..b298c88a6 100644 --- a/libguile/vm-i-system.c +++ b/libguile/vm-i-system.c @@ -1,18 +1,19 @@ /* Copyright (C) 2001,2008,2009 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ @@ -138,13 +139,62 @@ VM_DEFINE_INSTRUCTION (13, make_int16, "make-int16", 2, 0, 1) NEXT; } -VM_DEFINE_INSTRUCTION (14, make_char8, "make-char8", 1, 0, 1) +VM_DEFINE_INSTRUCTION (14, make_int64, "make-int64", 8, 0, 1) { - PUSH (SCM_MAKE_CHAR (FETCH ())); + scm_t_uint64 v = 0; + v += FETCH (); + v <<= 8; v += FETCH (); + v <<= 8; v += FETCH (); + v <<= 8; v += FETCH (); + v <<= 8; v += FETCH (); + v <<= 8; v += FETCH (); + v <<= 8; v += FETCH (); + v <<= 8; v += FETCH (); + PUSH (scm_from_int64 ((scm_t_int64) v)); NEXT; } -VM_DEFINE_INSTRUCTION (15, list, "list", 2, -1, 1) +VM_DEFINE_INSTRUCTION (15, make_uint64, "make-uint64", 8, 0, 1) +{ + scm_t_uint64 v = 0; + v += FETCH (); + v <<= 8; v += FETCH (); + v <<= 8; v += FETCH (); + v <<= 8; v += FETCH (); + v <<= 8; v += FETCH (); + v <<= 8; v += FETCH (); + v <<= 8; v += FETCH (); + v <<= 8; v += FETCH (); + PUSH (scm_from_uint64 (v)); + NEXT; +} + +VM_DEFINE_INSTRUCTION (16, make_char8, "make-char8", 1, 0, 1) +{ + scm_t_uint8 v = 0; + v = FETCH (); + + PUSH (SCM_MAKE_CHAR (v)); + /* Don't simplify this to PUSH (SCM_MAKE_CHAR (FETCH ())). The + contents of SCM_MAKE_CHAR may be evaluated more than once, + resulting in a double fetch. */ + NEXT; +} + +VM_DEFINE_INSTRUCTION (42, make_char32, "make-char32", 4, 0, 1) +{ + scm_t_wchar v = 0; + v += FETCH (); + v <<= 8; v += FETCH (); + v <<= 8; v += FETCH (); + v <<= 8; v += FETCH (); + PUSH (SCM_MAKE_CHAR (v)); + NEXT; +} + + + +VM_DEFINE_INSTRUCTION (17, list, "list", 2, -1, 1) { unsigned h = FETCH (); unsigned l = FETCH (); @@ -153,7 +203,7 @@ VM_DEFINE_INSTRUCTION (15, list, "list", 2, -1, 1) NEXT; } -VM_DEFINE_INSTRUCTION (16, vector, "vector", 2, -1, 1) +VM_DEFINE_INSTRUCTION (18, vector, "vector", 2, -1, 1) { unsigned h = FETCH (); unsigned l = FETCH (); @@ -171,19 +221,19 @@ VM_DEFINE_INSTRUCTION (16, vector, "vector", 2, -1, 1) NEXT; } -VM_DEFINE_INSTRUCTION (17, list_mark, "list-mark", 0, 0, 0) +VM_DEFINE_INSTRUCTION (19, list_mark, "list-mark", 0, 0, 0) { POP_LIST_MARK (); NEXT; } -VM_DEFINE_INSTRUCTION (18, cons_mark, "cons-mark", 0, 0, 0) +VM_DEFINE_INSTRUCTION (20, cons_mark, "cons-mark", 0, 0, 0) { POP_CONS_MARK (); NEXT; } -VM_DEFINE_INSTRUCTION (19, vector_mark, "vector-mark", 0, 0, 0) +VM_DEFINE_INSTRUCTION (21, vector_mark, "vector-mark", 0, 0, 0) { POP_LIST_MARK (); SYNC_REGISTER (); @@ -191,7 +241,7 @@ VM_DEFINE_INSTRUCTION (19, vector_mark, "vector-mark", 0, 0, 0) NEXT; } -VM_DEFINE_INSTRUCTION (20, list_break, "list-break", 0, 0, 0) +VM_DEFINE_INSTRUCTION (22, list_break, "list-break", 0, 0, 0) { SCM l; POP (l); @@ -217,9 +267,11 @@ VM_DEFINE_INSTRUCTION (20, list_break, "list-break", 0, 0, 0) #define VARIABLE_SET(v,o) SCM_VARIABLE_SET (v, o) #define VARIABLE_BOUNDP(v) (VARIABLE_REF (v) != SCM_UNDEFINED) +#define FREE_VARIABLE_REF(i) free_vars[i] + /* ref */ -VM_DEFINE_INSTRUCTION (21, object_ref, "object-ref", 1, 0, 1) +VM_DEFINE_INSTRUCTION (23, object_ref, "object-ref", 1, 0, 1) { register unsigned objnum = FETCH (); CHECK_OBJECT (objnum); @@ -227,33 +279,41 @@ VM_DEFINE_INSTRUCTION (21, object_ref, "object-ref", 1, 0, 1) NEXT; } -VM_DEFINE_INSTRUCTION (22, local_ref, "local-ref", 1, 0, 1) +/* FIXME: necessary? elt 255 of the vector could be a vector... */ +VM_DEFINE_INSTRUCTION (24, long_object_ref, "long-object-ref", 2, 0, 1) +{ + unsigned int objnum = FETCH (); + objnum <<= 8; + objnum += FETCH (); + CHECK_OBJECT (objnum); + PUSH (OBJECT_REF (objnum)); + NEXT; +} + +VM_DEFINE_INSTRUCTION (25, local_ref, "local-ref", 1, 0, 1) { PUSH (LOCAL_REF (FETCH ())); + ASSERT_BOUND (*sp); NEXT; } -VM_DEFINE_INSTRUCTION (23, external_ref, "external-ref", 1, 0, 1) +VM_DEFINE_INSTRUCTION (26, long_local_ref, "long-local-ref", 2, 0, 1) { - unsigned int i; - SCM e = external; - for (i = FETCH (); i; i--) - { - CHECK_EXTERNAL(e); - e = SCM_CDR (e); - } - CHECK_EXTERNAL(e); - PUSH (SCM_CAR (e)); + unsigned int i = FETCH (); + i <<= 8; + i += FETCH (); + PUSH (LOCAL_REF (i)); + ASSERT_BOUND (*sp); NEXT; } -VM_DEFINE_INSTRUCTION (24, variable_ref, "variable-ref", 0, 0, 1) +VM_DEFINE_INSTRUCTION (27, variable_ref, "variable-ref", 0, 0, 1) { SCM x = *sp; if (!VARIABLE_BOUNDP (x)) { - finish_args = SCM_LIST1 (x); + finish_args = scm_list_1 (x); /* Was: finish_args = SCM_LIST1 (SCM_CAR (x)); */ goto vm_error_unbound; } @@ -266,7 +326,7 @@ VM_DEFINE_INSTRUCTION (24, variable_ref, "variable-ref", 0, 0, 1) NEXT; } -VM_DEFINE_INSTRUCTION (25, toplevel_ref, "toplevel-ref", 1, 0, 1) +VM_DEFINE_INSTRUCTION (28, toplevel_ref, "toplevel-ref", 1, 0, 1) { unsigned objnum = FETCH (); SCM what; @@ -276,41 +336,37 @@ VM_DEFINE_INSTRUCTION (25, toplevel_ref, "toplevel-ref", 1, 0, 1) if (!SCM_VARIABLEP (what)) { SYNC_REGISTER (); - if (SCM_LIKELY (SCM_SYMBOLP (what))) - { - SCM mod = SCM_EOL; - if (SCM_LIKELY (scm_module_system_booted_p - && scm_is_true ((mod = scm_program_module (program))))) - /* might longjmp */ - what = scm_module_lookup (mod, what); - else - what = scm_sym2var (what, SCM_BOOL_F, SCM_BOOL_F); - } - else - { - SCM mod; - /* compilation of @ or @@ - `what' is a three-element list: (MODNAME SYM INTERFACE?) - INTERFACE? is #t if we compiled @ or #f if we compiled @@ - */ - mod = scm_resolve_module (SCM_CAR (what)); - if (scm_is_true (SCM_CADDR (what))) - mod = scm_module_public_interface (mod); - if (SCM_FALSEP (mod)) - { - finish_args = SCM_LIST1 (mod); - goto vm_error_no_such_module; - } - /* might longjmp */ - what = scm_module_lookup (mod, SCM_CADR (what)); - } - + what = resolve_variable (what, scm_program_module (program)); if (!VARIABLE_BOUNDP (what)) { - finish_args = SCM_LIST1 (what); + finish_args = scm_list_1 (what); goto vm_error_unbound; } + OBJECT_SET (objnum, what); + } + PUSH (VARIABLE_REF (what)); + NEXT; +} + +VM_DEFINE_INSTRUCTION (29, long_toplevel_ref, "long-toplevel-ref", 2, 0, 1) +{ + SCM what; + unsigned int objnum = FETCH (); + objnum <<= 8; + objnum += FETCH (); + CHECK_OBJECT (objnum); + what = OBJECT_REF (objnum); + + if (!SCM_VARIABLEP (what)) + { + SYNC_REGISTER (); + what = resolve_variable (what, scm_program_module (program)); + if (!VARIABLE_BOUNDP (what)) + { + finish_args = scm_list_1 (what); + goto vm_error_unbound; + } OBJECT_SET (objnum, what); } @@ -320,36 +376,31 @@ VM_DEFINE_INSTRUCTION (25, toplevel_ref, "toplevel-ref", 1, 0, 1) /* set */ -VM_DEFINE_INSTRUCTION (26, local_set, "local-set", 1, 1, 0) +VM_DEFINE_INSTRUCTION (30, local_set, "local-set", 1, 1, 0) { LOCAL_SET (FETCH (), *sp); DROP (); NEXT; } -VM_DEFINE_INSTRUCTION (27, external_set, "external-set", 1, 1, 0) +VM_DEFINE_INSTRUCTION (31, long_local_set, "long-local-set", 2, 1, 0) { - unsigned int i; - SCM e = external; - for (i = FETCH (); i; i--) - { - CHECK_EXTERNAL(e); - e = SCM_CDR (e); - } - CHECK_EXTERNAL(e); - SCM_SETCAR (e, *sp); + unsigned int i = FETCH (); + i <<= 8; + i += FETCH (); + LOCAL_SET (i, *sp); DROP (); NEXT; } -VM_DEFINE_INSTRUCTION (28, variable_set, "variable-set", 0, 1, 0) +VM_DEFINE_INSTRUCTION (32, variable_set, "variable-set", 0, 1, 0) { VARIABLE_SET (sp[0], sp[-1]); DROPN (2); NEXT; } -VM_DEFINE_INSTRUCTION (29, toplevel_set, "toplevel-set", 1, 1, 0) +VM_DEFINE_INSTRUCTION (33, toplevel_set, "toplevel-set", 1, 1, 0) { unsigned objnum = FETCH (); SCM what; @@ -359,35 +410,7 @@ VM_DEFINE_INSTRUCTION (29, toplevel_set, "toplevel-set", 1, 1, 0) if (!SCM_VARIABLEP (what)) { SYNC_BEFORE_GC (); - if (SCM_LIKELY (SCM_SYMBOLP (what))) - { - SCM mod = SCM_EOL; - if (SCM_LIKELY (scm_module_system_booted_p - && scm_is_true ((mod = scm_program_module (program))))) - /* might longjmp */ - what = scm_module_lookup (mod, what); - else - what = scm_sym2var (what, SCM_BOOL_F, SCM_BOOL_F); - } - else - { - SCM mod; - /* compilation of @ or @@ - `what' is a three-element list: (MODNAME SYM INTERFACE?) - INTERFACE? is #t if we compiled @ or #f if we compiled @@ - */ - mod = scm_resolve_module (SCM_CAR (what)); - if (scm_is_true (SCM_CADDR (what))) - mod = scm_module_public_interface (mod); - if (SCM_FALSEP (mod)) - { - finish_args = SCM_LIST1 (what); - goto vm_error_no_such_module; - } - /* might longjmp */ - what = scm_module_lookup (mod, SCM_CADR (what)); - } - + what = resolve_variable (what, scm_program_module (program)); OBJECT_SET (objnum, what); } @@ -396,9 +419,24 @@ VM_DEFINE_INSTRUCTION (29, toplevel_set, "toplevel-set", 1, 1, 0) NEXT; } -VM_DEFINE_INSTRUCTION (30, externals, "externals", 0, 0, 1) +VM_DEFINE_INSTRUCTION (34, long_toplevel_set, "long-toplevel-set", 2, 1, 0) { - PUSH (external); + SCM what; + unsigned int objnum = FETCH (); + objnum <<= 8; + objnum += FETCH (); + CHECK_OBJECT (objnum); + what = OBJECT_REF (objnum); + + if (!SCM_VARIABLEP (what)) + { + SYNC_BEFORE_GC (); + what = resolve_variable (what, scm_program_module (program)); + OBJECT_SET (objnum, what); + } + + VARIABLE_SET (what, *sp); + DROP (); NEXT; } @@ -407,7 +445,7 @@ VM_DEFINE_INSTRUCTION (30, externals, "externals", 0, 0, 1) * branch and jump */ -/* offset must be a signed short!!! */ +/* offset must be a signed 16 bit int!!! */ #define FETCH_OFFSET(offset) \ { \ int h = FETCH (); \ @@ -417,49 +455,51 @@ VM_DEFINE_INSTRUCTION (30, externals, "externals", 0, 0, 1) #define BR(p) \ { \ - signed short offset; \ + scm_t_int16 offset; \ FETCH_OFFSET (offset); \ if (p) \ - ip += offset; \ + ip += ((scm_t_ptrdiff)offset) * 8 - (((unsigned long)ip) % 8); \ NULLSTACK (1); \ DROP (); \ NEXT; \ } -VM_DEFINE_INSTRUCTION (31, br, "br", 2, 0, 0) +VM_DEFINE_INSTRUCTION (35, br, "br", 2, 0, 0) { - int h = FETCH (); - int l = FETCH (); - ip += (signed short) (h << 8) + l; + scm_t_int16 offset; + FETCH_OFFSET (offset); + ip += ((scm_t_ptrdiff)offset) * 8 - (((unsigned long)ip) % 8); NEXT; } -VM_DEFINE_INSTRUCTION (32, br_if, "br-if", 2, 0, 0) +VM_DEFINE_INSTRUCTION (36, br_if, "br-if", 2, 0, 0) { BR (!SCM_FALSEP (*sp)); } -VM_DEFINE_INSTRUCTION (33, br_if_not, "br-if-not", 2, 0, 0) +VM_DEFINE_INSTRUCTION (37, br_if_not, "br-if-not", 2, 0, 0) { BR (SCM_FALSEP (*sp)); } -VM_DEFINE_INSTRUCTION (34, br_if_eq, "br-if-eq", 2, 0, 0) +VM_DEFINE_INSTRUCTION (38, br_if_eq, "br-if-eq", 2, 0, 0) { - BR (SCM_EQ_P (sp[0], sp--[1])); + sp--; /* underflow? */ + BR (SCM_EQ_P (sp[0], sp[1])); } -VM_DEFINE_INSTRUCTION (35, br_if_not_eq, "br-if-not-eq", 2, 0, 0) +VM_DEFINE_INSTRUCTION (39, br_if_not_eq, "br-if-not-eq", 2, 0, 0) { - BR (!SCM_EQ_P (sp[0], sp--[1])); + sp--; /* underflow? */ + BR (!SCM_EQ_P (sp[0], sp[1])); } -VM_DEFINE_INSTRUCTION (36, br_if_null, "br-if-null", 2, 0, 0) +VM_DEFINE_INSTRUCTION (40, br_if_null, "br-if-null", 2, 0, 0) { BR (SCM_NULLP (*sp)); } -VM_DEFINE_INSTRUCTION (37, br_if_not_null, "br-if-not-null", 2, 0, 0) +VM_DEFINE_INSTRUCTION (41, br_if_not_null, "br-if-not-null", 2, 0, 0) { BR (!SCM_NULLP (*sp)); } @@ -469,15 +509,7 @@ VM_DEFINE_INSTRUCTION (37, br_if_not_null, "br-if-not-null", 2, 0, 0) * Subprogram call */ -VM_DEFINE_INSTRUCTION (38, make_closure, "make-closure", 0, 1, 1) -{ - SYNC_BEFORE_GC (); - SCM_NEWSMOB3 (*sp, scm_tc16_program, SCM_PROGRAM_OBJCODE (*sp), - SCM_PROGRAM_OBJTABLE (*sp), external); - NEXT; -} - -VM_DEFINE_INSTRUCTION (39, call, "call", 1, -1, 1) +VM_DEFINE_INSTRUCTION (43, call, "call", 1, -1, 1) { SCM x; nargs = FETCH (); @@ -598,7 +630,7 @@ VM_DEFINE_INSTRUCTION (39, call, "call", 1, -1, 1) goto vm_error_wrong_type_apply; } -VM_DEFINE_INSTRUCTION (40, goto_args, "goto/args", 1, -1, 1) +VM_DEFINE_INSTRUCTION (44, goto_args, "goto/args", 1, -1, 1) { register SCM x; nargs = FETCH (); @@ -625,12 +657,6 @@ VM_DEFINE_INSTRUCTION (40, goto_args, "goto/args", 1, -1, 1) sp -= 2; NULLSTACK (bp->nargs + 1); - /* Freshen the externals */ - external = SCM_PROGRAM_EXTERNALS (x); - for (i = 0; i < bp->nexts; i++) - CONS (external, SCM_UNDEFINED, external); - SCM_FRAME_DATA_ADDRESS (fp)[0] = external; - /* Init locals to valid SCM values */ for (i = 0; i < bp->nlocs; i++) LOCAL_SET (i + bp->nargs, SCM_UNDEFINED); @@ -679,7 +705,7 @@ VM_DEFINE_INSTRUCTION (40, goto_args, "goto/args", 1, -1, 1) sure we have space for the locals now */ data = SCM_FRAME_DATA_ADDRESS (fp); ip = bp->base; - stack_base = data + 3; + stack_base = data + 2; sp = stack_base; CHECK_OVERFLOW (); @@ -694,17 +720,9 @@ VM_DEFINE_INSTRUCTION (40, goto_args, "goto/args", 1, -1, 1) data[-i] = SCM_UNDEFINED; /* Set frame data */ - data[3] = (SCM)ra; - data[2] = (SCM)mvra; - data[1] = (SCM)dl; - - /* Postpone initializing external vars, because if the CONS causes a GC, - we want the stack marker to see the data array formatted as expected. */ - data[0] = SCM_UNDEFINED; - external = SCM_PROGRAM_EXTERNALS (fp[-1]); - for (i = 0; i < bp->nexts; i++) - CONS (external, SCM_UNDEFINED, external); - data[0] = external; + data[2] = (SCM)ra; + data[1] = (SCM)mvra; + data[0] = (SCM)dl; ENTER_HOOK (); APPLY_HOOK (); @@ -792,7 +810,7 @@ VM_DEFINE_INSTRUCTION (40, goto_args, "goto/args", 1, -1, 1) goto vm_error_wrong_type_apply; } -VM_DEFINE_INSTRUCTION (41, goto_nargs, "goto/nargs", 0, 0, 1) +VM_DEFINE_INSTRUCTION (45, goto_nargs, "goto/nargs", 0, 0, 1) { SCM x; POP (x); @@ -801,7 +819,7 @@ VM_DEFINE_INSTRUCTION (41, goto_nargs, "goto/nargs", 0, 0, 1) goto vm_goto_args; } -VM_DEFINE_INSTRUCTION (42, call_nargs, "call/nargs", 0, 0, 1) +VM_DEFINE_INSTRUCTION (46, call_nargs, "call/nargs", 0, 0, 1) { SCM x; POP (x); @@ -810,13 +828,15 @@ VM_DEFINE_INSTRUCTION (42, call_nargs, "call/nargs", 0, 0, 1) goto vm_call; } -VM_DEFINE_INSTRUCTION (43, mv_call, "mv-call", 3, -1, 1) +VM_DEFINE_INSTRUCTION (47, mv_call, "mv-call", 3, -1, 1) { SCM x; - signed short offset; + scm_t_int16 offset; + scm_t_uint8 *mvra; nargs = FETCH (); FETCH_OFFSET (offset); + mvra = ip + ((scm_t_ptrdiff)offset) * 8 - ((unsigned long)ip) % 8; x = sp[-nargs]; @@ -829,7 +849,7 @@ VM_DEFINE_INSTRUCTION (43, mv_call, "mv-call", 3, -1, 1) CACHE_PROGRAM (); INIT_ARGS (); NEW_FRAME (); - SCM_FRAME_DATA_ADDRESS (fp)[2] = (SCM)(SCM_FRAME_RETURN_ADDRESS (fp) + offset); + SCM_FRAME_DATA_ADDRESS (fp)[1] = (SCM)mvra; ENTER_HOOK (); APPLY_HOOK (); NEXT; @@ -854,7 +874,7 @@ VM_DEFINE_INSTRUCTION (43, mv_call, "mv-call", 3, -1, 1) len = scm_length (values); PUSH_LIST (values, SCM_NULLP); PUSH (len); - ip += offset; + ip = mvra; } NEXT; } @@ -871,7 +891,7 @@ VM_DEFINE_INSTRUCTION (43, mv_call, "mv-call", 3, -1, 1) goto vm_error_wrong_type_apply; } -VM_DEFINE_INSTRUCTION (44, apply, "apply", 1, -1, 1) +VM_DEFINE_INSTRUCTION (48, apply, "apply", 1, -1, 1) { int len; SCM ls; @@ -890,7 +910,7 @@ VM_DEFINE_INSTRUCTION (44, apply, "apply", 1, -1, 1) goto vm_call; } -VM_DEFINE_INSTRUCTION (45, goto_apply, "goto/apply", 1, -1, 1) +VM_DEFINE_INSTRUCTION (49, goto_apply, "goto/apply", 1, -1, 1) { int len; SCM ls; @@ -909,7 +929,7 @@ VM_DEFINE_INSTRUCTION (45, goto_apply, "goto/apply", 1, -1, 1) goto vm_goto_args; } -VM_DEFINE_INSTRUCTION (46, call_cc, "call/cc", 0, 1, 1) +VM_DEFINE_INSTRUCTION (50, call_cc, "call/cc", 0, 1, 1) { int first; SCM proc, cont; @@ -943,7 +963,7 @@ VM_DEFINE_INSTRUCTION (46, call_cc, "call/cc", 0, 1, 1) } } -VM_DEFINE_INSTRUCTION (47, goto_cc, "goto/cc", 0, 1, 1) +VM_DEFINE_INSTRUCTION (51, goto_cc, "goto/cc", 0, 1, 1) { int first; SCM proc, cont; @@ -975,7 +995,7 @@ VM_DEFINE_INSTRUCTION (47, goto_cc, "goto/cc", 0, 1, 1) } } -VM_DEFINE_INSTRUCTION (48, return, "return", 0, 1, 1) +VM_DEFINE_INSTRUCTION (52, return, "return", 0, 1, 1) { vm_return: EXIT_HOOK (); @@ -988,12 +1008,12 @@ VM_DEFINE_INSTRUCTION (48, return, "return", 0, 1, 1) POP (ret); ASSERT (sp == stack_base); - ASSERT (stack_base == data + 3); + ASSERT (stack_base == data + 2); /* Restore registers */ sp = SCM_FRAME_LOWER_ADDRESS (fp); - ip = SCM_FRAME_BYTE_CAST (data[3]); - fp = SCM_FRAME_STACK_CAST (data[1]); + ip = SCM_FRAME_BYTE_CAST (data[2]); + fp = SCM_FRAME_STACK_CAST (data[0]); { #ifdef VM_ENABLE_STACK_NULLING int nullcount = stack_base - sp; @@ -1009,12 +1029,11 @@ VM_DEFINE_INSTRUCTION (48, return, "return", 0, 1, 1) /* Restore the last program */ program = SCM_FRAME_PROGRAM (fp); CACHE_PROGRAM (); - CACHE_EXTERNAL (); CHECK_IP (); NEXT; } -VM_DEFINE_INSTRUCTION (49, return_values, "return/values", 1, -1, -1) +VM_DEFINE_INSTRUCTION (53, return_values, "return/values", 1, -1, -1) { /* nvalues declared at top level, because for some reason gcc seems to think that perhaps it might be used without declaration. Fooey to that, I say. */ @@ -1026,16 +1045,16 @@ VM_DEFINE_INSTRUCTION (49, return_values, "return/values", 1, -1, -1) RETURN_HOOK (); data = SCM_FRAME_DATA_ADDRESS (fp); - ASSERT (stack_base == data + 3); + ASSERT (stack_base == data + 2); - /* data[2] is the mv return address */ - if (nvalues != 1 && data[2]) + /* data[1] is the mv return address */ + if (nvalues != 1 && data[1]) { int i; /* Restore registers */ sp = SCM_FRAME_LOWER_ADDRESS (fp) - 1; - ip = SCM_FRAME_BYTE_CAST (data[2]); /* multiple value ra */ - fp = SCM_FRAME_STACK_CAST (data[1]); + ip = SCM_FRAME_BYTE_CAST (data[1]); /* multiple value ra */ + fp = SCM_FRAME_STACK_CAST (data[0]); /* Push return values, and the number of values */ for (i = 0; i < nvalues; i++) @@ -1054,8 +1073,8 @@ VM_DEFINE_INSTRUCTION (49, return_values, "return/values", 1, -1, -1) continuation.) */ /* Restore registers */ sp = SCM_FRAME_LOWER_ADDRESS (fp) - 1; - ip = SCM_FRAME_BYTE_CAST (data[3]); /* single value ra */ - fp = SCM_FRAME_STACK_CAST (data[1]); + ip = SCM_FRAME_BYTE_CAST (data[2]); /* single value ra */ + fp = SCM_FRAME_STACK_CAST (data[0]); /* Push first value */ *++sp = stack_base[1]; @@ -1070,12 +1089,11 @@ VM_DEFINE_INSTRUCTION (49, return_values, "return/values", 1, -1, -1) /* Restore the last program */ program = SCM_FRAME_PROGRAM (fp); CACHE_PROGRAM (); - CACHE_EXTERNAL (); CHECK_IP (); NEXT; } -VM_DEFINE_INSTRUCTION (50, return_values_star, "return/values*", 1, -1, -1) +VM_DEFINE_INSTRUCTION (54, return_values_star, "return/values*", 1, -1, -1) { SCM l; @@ -1098,7 +1116,7 @@ VM_DEFINE_INSTRUCTION (50, return_values_star, "return/values*", 1, -1, -1) goto vm_return_values; } -VM_DEFINE_INSTRUCTION (51, truncate_values, "truncate-values", 2, -1, -1) +VM_DEFINE_INSTRUCTION (55, truncate_values, "truncate-values", 2, -1, -1) { SCM x; int nbinds, rest; @@ -1121,6 +1139,142 @@ VM_DEFINE_INSTRUCTION (51, truncate_values, "truncate-values", 2, -1, -1) NEXT; } +VM_DEFINE_INSTRUCTION (56, box, "box", 1, 1, 0) +{ + SCM val; + POP (val); + SYNC_BEFORE_GC (); + LOCAL_SET (FETCH (), scm_cell (scm_tc7_variable, SCM_UNPACK (val))); + NEXT; +} + +/* for letrec: + (let ((a *undef*) (b *undef*) ...) + (set! a (lambda () (b ...))) + ...) + */ +VM_DEFINE_INSTRUCTION (57, empty_box, "empty-box", 1, 0, 0) +{ + SYNC_BEFORE_GC (); + LOCAL_SET (FETCH (), + scm_cell (scm_tc7_variable, SCM_UNPACK (SCM_UNDEFINED))); + NEXT; +} + +VM_DEFINE_INSTRUCTION (58, local_boxed_ref, "local-boxed-ref", 1, 0, 1) +{ + SCM v = LOCAL_REF (FETCH ()); + ASSERT_BOUND_VARIABLE (v); + PUSH (VARIABLE_REF (v)); + NEXT; +} + +VM_DEFINE_INSTRUCTION (59, local_boxed_set, "local-boxed-set", 1, 1, 0) +{ + SCM v, val; + v = LOCAL_REF (FETCH ()); + POP (val); + ASSERT_VARIABLE (v); + VARIABLE_SET (v, val); + NEXT; +} + +VM_DEFINE_INSTRUCTION (60, free_ref, "free-ref", 1, 0, 1) +{ + scm_t_uint8 idx = FETCH (); + + CHECK_FREE_VARIABLE (idx); + PUSH (FREE_VARIABLE_REF (idx)); + NEXT; +} + +/* no free-set -- if a var is assigned, it should be in a box */ + +VM_DEFINE_INSTRUCTION (61, free_boxed_ref, "free-boxed-ref", 1, 0, 1) +{ + SCM v; + scm_t_uint8 idx = FETCH (); + CHECK_FREE_VARIABLE (idx); + v = FREE_VARIABLE_REF (idx); + ASSERT_BOUND_VARIABLE (v); + PUSH (VARIABLE_REF (v)); + NEXT; +} + +VM_DEFINE_INSTRUCTION (62, free_boxed_set, "free-boxed-set", 1, 1, 0) +{ + SCM v, val; + scm_t_uint8 idx = FETCH (); + POP (val); + CHECK_FREE_VARIABLE (idx); + v = FREE_VARIABLE_REF (idx); + ASSERT_BOUND_VARIABLE (v); + VARIABLE_SET (v, val); + NEXT; +} + +VM_DEFINE_INSTRUCTION (63, make_closure, "make-closure", 0, 2, 1) +{ + SCM vect; + POP (vect); + SYNC_BEFORE_GC (); + /* fixme underflow */ + SCM_NEWSMOB3 (*sp, scm_tc16_program, SCM_PROGRAM_OBJCODE (*sp), + SCM_PROGRAM_OBJTABLE (*sp), vect); + NEXT; +} + +VM_DEFINE_INSTRUCTION (64, make_variable, "make-variable", 0, 0, 1) +{ + SYNC_BEFORE_GC (); + /* fixme underflow */ + PUSH (scm_cell (scm_tc7_variable, SCM_UNPACK (SCM_UNDEFINED))); + NEXT; +} + +VM_DEFINE_INSTRUCTION (65, fix_closure, "fix-closure", 2, 0, 1) +{ + SCM x, vect; + unsigned int i = FETCH (); + i <<= 8; + i += FETCH (); + POP (vect); + /* FIXME CHECK_LOCAL (i) */ + x = LOCAL_REF (i); + /* FIXME ASSERT_PROGRAM (x); */ + SCM_SET_CELL_WORD_3 (x, vect); + NEXT; +} + +VM_DEFINE_INSTRUCTION (66, define, "define", 0, 0, 2) +{ + SCM sym, val; + POP (sym); + POP (val); + SYNC_REGISTER (); + VARIABLE_SET (scm_sym2var (sym, scm_current_module_lookup_closure (), + SCM_BOOL_T), + val); + NEXT; +} + +VM_DEFINE_INSTRUCTION (67, make_keyword, "make-keyword", 0, 1, 1) +{ + CHECK_UNDERFLOW (); + SYNC_REGISTER (); + *sp = scm_symbol_to_keyword (*sp); + NEXT; +} + +VM_DEFINE_INSTRUCTION (68, make_symbol, "make-symbol", 0, 1, 1) +{ + CHECK_UNDERFLOW (); + SYNC_REGISTER (); + *sp = scm_string_to_symbol (*sp); + NEXT; +} + + /* (defun renumber-ops () "start from top of buffer and renumber 'VM_DEFINE_FOO (\n' sequences" diff --git a/libguile/vm.c b/libguile/vm.c index e132c8eda..df1ad8850 100644 --- a/libguile/vm.c +++ b/libguile/vm.c @@ -1,50 +1,29 @@ -/* Copyright (C) 2001 Free Software Foundation, Inc. - * - * 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 2, or (at your option) - * any later version. +/* Copyright (C) 2001, 2009 Free Software Foundation, Inc. * - * 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 software; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307 USA + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * As a special exception, the Free Software Foundation gives permission - * for additional uses of the text contained in its release of GUILE. + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * The exception is that, if you link the GUILE library with other files - * to produce an executable, this does not by itself cause the - * resulting executable to be covered by the GNU General Public License. - * Your use of that executable is in no way restricted on account of - * linking the GUILE library code into it. - * - * This exception does not however invalidate any other reasons why - * the executable file might be covered by the GNU General Public License. - * - * This exception applies only to the code released by the - * Free Software Foundation under the name GUILE. If you copy - * code from other Free Software Foundation releases into a copy of - * GUILE, as the General Public License permits, the exception does - * not apply to the code that you add in this way. To avoid misleading - * anyone as to the status of such modified files, you must delete - * this exception notice from them. - * - * If you write modifications of your own for GUILE, it is your choice - * whether to permit this exception to apply to your modifications. - * If you do not wish that, delete this exception notice. */ + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ #if HAVE_CONFIG_H # include #endif +#include #include #include +#include "_scm.h" #include "vm-bootstrap.h" #include "frames.h" #include "instructions.h" @@ -185,28 +164,37 @@ static SCM sym_vm_run; static SCM sym_vm_error; static SCM sym_debug; -static SCM make_u8vector (const scm_t_uint8 *bytes, size_t len) -{ - scm_t_uint8 *new_bytes = scm_gc_malloc (len, "make-u8vector"); - memcpy (new_bytes, bytes, len); - return scm_take_u8vector (new_bytes, len); -} - static SCM really_make_boot_program (long nargs) { - scm_byte_t bytes[] = {0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - scm_op_mv_call, 0, 0, 1, scm_op_make_int8_1, scm_op_halt}; + SCM u8vec; + /* Make sure "bytes" is 64-bit aligned. */ + scm_t_uint8 text[] = { scm_op_mv_call, 0, 0, 1, + scm_op_make_int8_1, scm_op_nop, scm_op_nop, scm_op_nop, + scm_op_halt }; + struct scm_objcode *bp; SCM ret; - ((scm_t_uint32*)bytes)[1] = 6; /* set len in current endianness, no meta */ + if (SCM_UNLIKELY (nargs > 255 || nargs < 0)) abort (); - bytes[13] = (scm_byte_t)nargs; - ret = scm_make_program (scm_bytecode_to_objcode (make_u8vector (bytes, sizeof(bytes))), - SCM_BOOL_F, SCM_EOL); + text[1] = (scm_t_uint8)nargs; + + bp = scm_gc_malloc (sizeof (struct scm_objcode) + sizeof (text), + "make-u8vector"); + memcpy (bp->base, text, sizeof (text)); + bp->nargs = 0; + bp->nrest = 0; + bp->nlocs = 0; + bp->len = sizeof(text); + bp->metalen = 0; + bp->unused = 0; + + u8vec = scm_take_u8vector ((scm_t_uint8*)bp, + sizeof (struct scm_objcode) + sizeof (text)); + ret = scm_make_program (scm_bytecode_to_objcode (u8vec), + SCM_BOOL_F, SCM_BOOL_F); SCM_SET_SMOB_FLAGS (ret, SCM_F_PROGRAM_IS_BOOT); + return ret; } #define NUM_BOOT_PROGS 8 @@ -233,7 +221,44 @@ vm_make_boot_program (long nargs) * VM */ -#define VM_DEFAULT_STACK_SIZE (16 * 1024) +static SCM +resolve_variable (SCM what, SCM program_module) +{ + if (SCM_LIKELY (SCM_SYMBOLP (what))) + { + if (SCM_LIKELY (scm_module_system_booted_p + && scm_is_true (program_module))) + /* might longjmp */ + return scm_module_lookup (program_module, what); + else + { + SCM v = scm_sym2var (what, SCM_BOOL_F, SCM_BOOL_F); + if (scm_is_false (v)) + scm_misc_error (NULL, "unbound variable: ~S", scm_list_1 (what)); + else + return v; + } + } + else + { + SCM mod; + /* compilation of @ or @@ + `what' is a three-element list: (MODNAME SYM INTERFACE?) + INTERFACE? is #t if we compiled @ or #f if we compiled @@ + */ + mod = scm_resolve_module (SCM_CAR (what)); + if (scm_is_true (SCM_CADDR (what))) + mod = scm_module_public_interface (mod); + if (SCM_FALSEP (mod)) + scm_misc_error (NULL, "no such module: ~S", + scm_list_1 (SCM_CAR (what))); + /* might longjmp */ + return scm_module_lookup (mod, SCM_CADR (what)); + } +} + + +#define VM_DEFAULT_STACK_SIZE (64 * 1024) #define VM_NAME vm_regular_engine #define FUNC_NAME "vm-regular-engine" @@ -535,7 +560,7 @@ SCM_DEFINE (scm_vm_trace_frame, "vm-trace-frame", 1, 0, 0, SCM scm_load_compiled_with_vm (SCM file) { SCM program = scm_make_program (scm_load_objcode (file), - SCM_BOOL_F, SCM_EOL); + SCM_BOOL_F, SCM_BOOL_F); return scm_c_vm_run (scm_the_vm (), program, NULL, 0); } @@ -566,6 +591,9 @@ scm_bootstrap_vm (void) sym_vm_error = scm_permanent_object (scm_from_locale_symbol ("vm-error")); sym_debug = scm_permanent_object (scm_from_locale_symbol ("debug")); + scm_c_register_extension ("libguile", "scm_init_vm", + (scm_t_extension_init_func)scm_init_vm, NULL); + strappage = 1; } diff --git a/libguile/vm.h b/libguile/vm.h index 5c38f9ffa..b079c7aa0 100644 --- a/libguile/vm.h +++ b/libguile/vm.h @@ -1,43 +1,20 @@ /* Copyright (C) 2001 Free Software Foundation, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * 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 2, or (at your option) - * any later version. + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * 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 software; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307 USA - * - * As a special exception, the Free Software Foundation gives permission - * for additional uses of the text contained in its release of GUILE. - * - * The exception is that, if you link the GUILE library with other files - * to produce an executable, this does not by itself cause the - * resulting executable to be covered by the GNU General Public License. - * Your use of that executable is in no way restricted on account of - * linking the GUILE library code into it. - * - * This exception does not however invalidate any other reasons why - * the executable file might be covered by the GNU General Public License. - * - * This exception applies only to the code released by the - * Free Software Foundation under the name GUILE. If you copy - * code from other Free Software Foundation releases into a copy of - * GUILE, as the General Public License permits, the exception does - * not apply to the code that you add in this way. To avoid misleading - * anyone as to the status of such modified files, you must delete - * this exception notice from them. - * - * If you write modifications of your own for GUILE, it is your choice - * whether to permit this exception to apply to your modifications. - * If you do not wish that, delete this exception notice. */ + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ #ifndef _SCM_VM_H_ #define _SCM_VM_H_ @@ -78,37 +55,37 @@ struct scm_vm { SCM trace_frame; /* a frame being traced */ }; -extern SCM scm_the_vm_fluid; +SCM_API SCM scm_the_vm_fluid; #define SCM_VM_P(x) SCM_SMOB_PREDICATE (scm_tc16_vm, x) #define SCM_VM_DATA(vm) ((struct scm_vm *) SCM_SMOB_DATA (vm)) #define SCM_VALIDATE_VM(pos,x) SCM_MAKE_VALIDATE (pos, x, VM_P) -extern SCM scm_the_vm (); -extern SCM scm_make_vm (void); -extern SCM scm_vm_apply (SCM vm, SCM program, SCM args); -extern SCM scm_c_vm_run (SCM vm, SCM program, SCM *argv, int nargs); -extern SCM scm_vm_option_ref (SCM vm, SCM key); -extern SCM scm_vm_option_set_x (SCM vm, SCM key, SCM val); +SCM_API SCM scm_the_vm (); +SCM_API SCM scm_make_vm (void); +SCM_API SCM scm_vm_apply (SCM vm, SCM program, SCM args); +SCM_API SCM scm_c_vm_run (SCM vm, SCM program, SCM *argv, int nargs); +SCM_API SCM scm_vm_option_ref (SCM vm, SCM key); +SCM_API SCM scm_vm_option_set_x (SCM vm, SCM key, SCM val); -extern SCM scm_vm_version (void); -extern SCM scm_the_vm (void); -extern SCM scm_vm_p (SCM obj); -extern SCM scm_vm_ip (SCM vm); -extern SCM scm_vm_sp (SCM vm); -extern SCM scm_vm_fp (SCM vm); -extern SCM scm_vm_boot_hook (SCM vm); -extern SCM scm_vm_halt_hook (SCM vm); -extern SCM scm_vm_next_hook (SCM vm); -extern SCM scm_vm_break_hook (SCM vm); -extern SCM scm_vm_enter_hook (SCM vm); -extern SCM scm_vm_apply_hook (SCM vm); -extern SCM scm_vm_exit_hook (SCM vm); -extern SCM scm_vm_return_hook (SCM vm); -extern SCM scm_vm_option (SCM vm, SCM key); -extern SCM scm_set_vm_option_x (SCM vm, SCM key, SCM val); -extern SCM scm_vm_stats (SCM vm); -extern SCM scm_vm_trace_frame (SCM vm); +SCM_API SCM scm_vm_version (void); +SCM_API SCM scm_the_vm (void); +SCM_API SCM scm_vm_p (SCM obj); +SCM_API SCM scm_vm_ip (SCM vm); +SCM_API SCM scm_vm_sp (SCM vm); +SCM_API SCM scm_vm_fp (SCM vm); +SCM_API SCM scm_vm_boot_hook (SCM vm); +SCM_API SCM scm_vm_halt_hook (SCM vm); +SCM_API SCM scm_vm_next_hook (SCM vm); +SCM_API SCM scm_vm_break_hook (SCM vm); +SCM_API SCM scm_vm_enter_hook (SCM vm); +SCM_API SCM scm_vm_apply_hook (SCM vm); +SCM_API SCM scm_vm_exit_hook (SCM vm); +SCM_API SCM scm_vm_return_hook (SCM vm); +SCM_API SCM scm_vm_option (SCM vm, SCM key); +SCM_API SCM scm_set_vm_option_x (SCM vm, SCM key, SCM val); +SCM_API SCM scm_vm_stats (SCM vm); +SCM_API SCM scm_vm_trace_frame (SCM vm); struct scm_vm_cont { scm_byte_t *ip; @@ -119,16 +96,16 @@ struct scm_vm_cont { scm_t_ptrdiff reloc; }; -extern scm_t_bits scm_tc16_vm_cont; +SCM_API scm_t_bits scm_tc16_vm_cont; #define SCM_VM_CONT_P(OBJ) SCM_SMOB_PREDICATE (scm_tc16_vm_cont, OBJ) #define SCM_VM_CONT_DATA(CONT) ((struct scm_vm_cont *) SCM_CELL_WORD_1 (CONT)) -extern SCM scm_vm_capture_continuations (void); -extern void scm_vm_reinstate_continuations (SCM conts); +SCM_API SCM scm_vm_capture_continuations (void); +SCM_API void scm_vm_reinstate_continuations (SCM conts); -extern SCM scm_load_compiled_with_vm (SCM file); +SCM_API SCM scm_load_compiled_with_vm (SCM file); -extern void scm_init_vm (void); +SCM_INTERNAL void scm_init_vm (void); #endif /* _SCM_VM_H_ */ diff --git a/libguile/vports.c b/libguile/vports.c index 564f0e73f..cea11c61d 100644 --- a/libguile/vports.c +++ b/libguile/vports.c @@ -1,18 +1,19 @@ /* Copyright (C) 1995,1996,1998,1999,2000,2001, 2002, 2003, 2006 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/vports.h b/libguile/vports.h index 365303bc1..ae64dd438 100644 --- a/libguile/vports.h +++ b/libguile/vports.h @@ -6,18 +6,19 @@ /* Copyright (C) 1995,1996,2000, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/weaks.c b/libguile/weaks.c index 7558e78a6..92fb305cc 100644 --- a/libguile/weaks.c +++ b/libguile/weaks.c @@ -1,18 +1,19 @@ /* Copyright (C) 1995,1996,1998,2000,2001, 2003, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/weaks.h b/libguile/weaks.h index 81c17749f..908e27628 100644 --- a/libguile/weaks.h +++ b/libguile/weaks.h @@ -6,18 +6,19 @@ /* Copyright (C) 1995,1996,2000,2001, 2003, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/win32-dirent.c b/libguile/win32-dirent.c index cd7e8bac6..de170c70b 100644 --- a/libguile/win32-dirent.c +++ b/libguile/win32-dirent.c @@ -1,18 +1,19 @@ /* Copyright (C) 2001, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ #ifdef HAVE_CONFIG_H diff --git a/libguile/win32-dirent.h b/libguile/win32-dirent.h index 30bc118ea..578db49b9 100644 --- a/libguile/win32-dirent.h +++ b/libguile/win32-dirent.h @@ -6,18 +6,19 @@ /* Copyright (C) 2001, 2006 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ /* Directory stream type. diff --git a/libguile/win32-socket.c b/libguile/win32-socket.c index 54f80a764..e845d886a 100644 --- a/libguile/win32-socket.c +++ b/libguile/win32-socket.c @@ -1,18 +1,19 @@ /* Copyright (C) 2001, 2006 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/libguile/win32-socket.h b/libguile/win32-socket.h index 51856051d..4ab9b942a 100644 --- a/libguile/win32-socket.h +++ b/libguile/win32-socket.h @@ -6,18 +6,19 @@ /* Copyright (C) 2001, 2006 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ #include "libguile/__scm.h" diff --git a/libguile/win32-uname.c b/libguile/win32-uname.c index d4d737f49..5349f1410 100644 --- a/libguile/win32-uname.c +++ b/libguile/win32-uname.c @@ -1,18 +1,19 @@ /* Copyright (C) 2001, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ #ifdef HAVE_CONFIG_H diff --git a/libguile/win32-uname.h b/libguile/win32-uname.h index 8593dc7d9..4b7498133 100644 --- a/libguile/win32-uname.h +++ b/libguile/win32-uname.h @@ -6,18 +6,19 @@ /* Copyright (C) 2001, 2006 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ #define _UTSNAME_LENGTH 65 diff --git a/m4/00gnulib.m4 b/m4/00gnulib.m4 new file mode 100644 index 000000000..d4d04d153 --- /dev/null +++ b/m4/00gnulib.m4 @@ -0,0 +1,30 @@ +# 00gnulib.m4 serial 2 +dnl Copyright (C) 2009 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl This file must be named something that sorts before all other +dnl gnulib-provided .m4 files. It is needed until such time as we can +dnl assume Autoconf 2.64, with its improved AC_DEFUN_ONCE semantics. + +# AC_DEFUN_ONCE([NAME], VALUE) +# ---------------------------- +# Define NAME to expand to VALUE on the first use (whether by direct +# expansion, or by AC_REQUIRE), and to nothing on all subsequent uses. +# Avoid bugs in AC_REQUIRE in Autoconf 2.63 and earlier. This +# definition is slower than the version in Autoconf 2.64, because it +# can only use interfaces that existed since 2.59; but it achieves the +# same effect. Quoting is necessary to avoid confusing Automake. +m4_version_prereq([2.63.263], [], +[m4_define([AC][_DEFUN_ONCE], + [AC][_DEFUN([$1], + [AC_REQUIRE([_gl_DEFUN_ONCE([$1])], + [m4_indir([_gl_DEFUN_ONCE([$1])])])])]dnl +[AC][_DEFUN([_gl_DEFUN_ONCE([$1])], [$2])])]) + +# gl_00GNULIB +# ----------- +# Witness macro that this file has been included. Needed to force +# Automake to include this file prior to all other gnulib .m4 files. +AC_DEFUN([gl_00GNULIB]) diff --git a/m4/alloca.m4 b/m4/alloca.m4 index 95f54a6d4..4b978e137 100644 --- a/m4/alloca.m4 +++ b/m4/alloca.m4 @@ -1,5 +1,5 @@ -# alloca.m4 serial 8 -dnl Copyright (C) 2002-2004, 2006, 2007 Free Software Foundation, Inc. +# alloca.m4 serial 9 +dnl Copyright (C) 2002-2004, 2006, 2007, 2009 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. @@ -26,7 +26,7 @@ AC_DEFUN([gl_FUNC_ALLOCA], ]) if test $gl_cv_rpl_alloca = yes; then dnl OK, alloca can be implemented through a compiler built-in. - AC_DEFINE([HAVE_ALLOCA], 1, + AC_DEFINE([HAVE_ALLOCA], [1], [Define to 1 if you have 'alloca' after including , a header that may be supplied by this distribution.]) ALLOCA_H=alloca.h diff --git a/m4/byteswap.m4 b/m4/byteswap.m4 new file mode 100644 index 000000000..ad13f2286 --- /dev/null +++ b/m4/byteswap.m4 @@ -0,0 +1,18 @@ +# byteswap.m4 serial 3 +dnl Copyright (C) 2005, 2007, 2009 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl Written by Oskar Liljeblad. + +AC_DEFUN([gl_BYTESWAP], +[ + dnl Prerequisites of lib/byteswap.in.h. + AC_CHECK_HEADERS([byteswap.h], [ + BYTESWAP_H='' + ], [ + BYTESWAP_H='byteswap.h' + ]) + AC_SUBST([BYTESWAP_H]) +]) diff --git a/m4/canonicalize-lgpl.m4 b/m4/canonicalize-lgpl.m4 new file mode 100644 index 000000000..3a8ee2f95 --- /dev/null +++ b/m4/canonicalize-lgpl.m4 @@ -0,0 +1,35 @@ +# canonicalize-lgpl.m4 serial 5 +dnl Copyright (C) 2003, 2006-2007, 2009 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_CANONICALIZE_LGPL], +[ + dnl Do this replacement check manually because the file name is shorter + dnl than the function name. + AC_CHECK_DECLS_ONCE([canonicalize_file_name]) + AC_CHECK_FUNCS_ONCE([canonicalize_file_name]) + if test $ac_cv_func_canonicalize_file_name = no; then + AC_LIBOBJ([canonicalize-lgpl]) + AC_DEFINE([realpath], [rpl_realpath], + [Define to a replacement function name for realpath().]) + gl_PREREQ_CANONICALIZE_LGPL + fi +]) + +# Like gl_CANONICALIZE_LGPL, except prepare for separate compilation +# (no AC_LIBOBJ). +AC_DEFUN([gl_CANONICALIZE_LGPL_SEPARATE], +[ + AC_CHECK_DECLS_ONCE([canonicalize_file_name]) + AC_CHECK_FUNCS_ONCE([canonicalize_file_name]) + gl_PREREQ_CANONICALIZE_LGPL +]) + +# Prerequisites of lib/canonicalize-lgpl.c. +AC_DEFUN([gl_PREREQ_CANONICALIZE_LGPL], +[ + AC_CHECK_HEADERS_ONCE([sys/param.h unistd.h]) + AC_CHECK_FUNCS_ONCE([getcwd readlink]) +]) diff --git a/m4/codeset.m4 b/m4/codeset.m4 index de4181d7d..413217bd4 100644 --- a/m4/codeset.m4 +++ b/m4/codeset.m4 @@ -1,5 +1,5 @@ -# codeset.m4 serial 3 (gettext-0.18) -dnl Copyright (C) 2000-2002, 2006, 2008 Free Software Foundation, Inc. +# codeset.m4 serial 4 (gettext-0.18) +dnl Copyright (C) 2000-2002, 2006, 2008, 2009 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. @@ -15,7 +15,7 @@ AC_DEFUN([AM_LANGINFO_CODESET], [am_cv_langinfo_codeset=no]) ]) if test $am_cv_langinfo_codeset = yes; then - AC_DEFINE([HAVE_LANGINFO_CODESET], 1, + AC_DEFINE([HAVE_LANGINFO_CODESET], [1], [Define if you have and nl_langinfo(CODESET).]) fi ]) diff --git a/m4/eealloc.m4 b/m4/eealloc.m4 new file mode 100644 index 000000000..3c9c0b52a --- /dev/null +++ b/m4/eealloc.m4 @@ -0,0 +1,32 @@ +# eealloc.m4 serial 2 +dnl Copyright (C) 2003, 2009 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_EEALLOC], +[ + AC_REQUIRE([gl_EEMALLOC]) + AC_REQUIRE([gl_EEREALLOC]) + AC_REQUIRE([AC_C_INLINE]) +]) + +AC_DEFUN([gl_EEMALLOC], +[ + _AC_FUNC_MALLOC_IF( + [gl_cv_func_malloc_0_nonnull=1], + [gl_cv_func_malloc_0_nonnull=0]) + AC_DEFINE_UNQUOTED([MALLOC_0_IS_NONNULL], [$gl_cv_func_malloc_0_nonnull], + [If malloc(0) is != NULL, define this to 1. Otherwise define this + to 0.]) +]) + +AC_DEFUN([gl_EEREALLOC], +[ + _AC_FUNC_REALLOC_IF( + [gl_cv_func_realloc_0_nonnull=1], + [gl_cv_func_realloc_0_nonnull=0]) + AC_DEFINE_UNQUOTED([REALLOC_0_IS_NONNULL], [$gl_cv_func_realloc_0_nonnull], + [If realloc(NULL,0) is != NULL, define this to 1. Otherwise define this + to 0.]) +]) diff --git a/m4/environ.m4 b/m4/environ.m4 new file mode 100644 index 000000000..b17bb60a7 --- /dev/null +++ b/m4/environ.m4 @@ -0,0 +1,36 @@ +# environ.m4 serial 2 +dnl Copyright (C) 2001-2004, 2006-2009 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_ENVIRON], +[ + AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) + dnl Persuade glibc to declare environ. + AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) + gt_CHECK_VAR_DECL([#include ], environ) + if test $gt_cv_var_environ_declaration != yes; then + HAVE_DECL_ENVIRON=0 + fi +]) + +# Check if a variable is properly declared. +# gt_CHECK_VAR_DECL(includes,variable) +AC_DEFUN([gt_CHECK_VAR_DECL], +[ + define([gt_cv_var], [gt_cv_var_]$2[_declaration]) + AC_MSG_CHECKING([if $2 is properly declared]) + AC_CACHE_VAL([gt_cv_var], [ + AC_TRY_COMPILE([$1 + extern struct { int foo; } $2;], + [$2.foo = 1;], + gt_cv_var=no, + gt_cv_var=yes)]) + AC_MSG_RESULT([$gt_cv_var]) + if test $gt_cv_var = yes; then + AC_DEFINE([HAVE_]translit($2, [a-z], [A-Z])[_DECL], 1, + [Define if you have the declaration of $2.]) + fi + undefine([gt_cv_var]) +]) diff --git a/m4/errno_h.m4 b/m4/errno_h.m4 new file mode 100644 index 000000000..4ce1ccbd9 --- /dev/null +++ b/m4/errno_h.m4 @@ -0,0 +1,115 @@ +# errno_h.m4 serial 6 +dnl Copyright (C) 2004, 2006, 2008, 2009 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN_ONCE([gl_HEADER_ERRNO_H], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_CACHE_CHECK([for complete errno.h], [gl_cv_header_errno_h_complete], [ + AC_EGREP_CPP([booboo],[ +#include +#if !defined ENOMSG +booboo +#endif +#if !defined EIDRM +booboo +#endif +#if !defined ENOLINK +booboo +#endif +#if !defined EPROTO +booboo +#endif +#if !defined EMULTIHOP +booboo +#endif +#if !defined EBADMSG +booboo +#endif +#if !defined EOVERFLOW +booboo +#endif +#if !defined ENOTSUP +booboo +#endif +#if !defined ESTALE +booboo +#endif +#if !defined ECANCELED +booboo +#endif + ], + [gl_cv_header_errno_h_complete=no], + [gl_cv_header_errno_h_complete=yes]) + ]) + if test $gl_cv_header_errno_h_complete = yes; then + ERRNO_H='' + else + gl_CHECK_NEXT_HEADERS([errno.h]) + ERRNO_H='errno.h' + fi + AC_SUBST([ERRNO_H]) + gl_REPLACE_ERRNO_VALUE([EMULTIHOP]) + gl_REPLACE_ERRNO_VALUE([ENOLINK]) + gl_REPLACE_ERRNO_VALUE([EOVERFLOW]) +]) + +# Assuming $1 = EOVERFLOW. +# The EOVERFLOW errno value ought to be defined in , according to +# POSIX. But some systems (like OpenBSD 4.0 or AIX 3) don't define it, and +# some systems (like OSF/1) define it when _XOPEN_SOURCE_EXTENDED is defined. +# Check for the value of EOVERFLOW. +# Set the variables EOVERFLOW_HIDDEN and EOVERFLOW_VALUE. +AC_DEFUN([gl_REPLACE_ERRNO_VALUE], +[ + if test -n "$ERRNO_H"; then + AC_CACHE_CHECK([for ]$1[ value], [gl_cv_header_errno_h_]$1, [ + AC_EGREP_CPP([yes],[ +#include +#ifdef ]$1[ +yes +#endif + ], + [gl_cv_header_errno_h_]$1[=yes], + [gl_cv_header_errno_h_]$1[=no]) + if test $gl_cv_header_errno_h_]$1[ = no; then + AC_EGREP_CPP([yes],[ +#define _XOPEN_SOURCE_EXTENDED 1 +#include +#ifdef ]$1[ +yes +#endif + ], [gl_cv_header_errno_h_]$1[=hidden]) + if test $gl_cv_header_errno_h_]$1[ = hidden; then + dnl The macro exists but is hidden. + dnl Define it to the same value. + AC_COMPUTE_INT([gl_cv_header_errno_h_]$1, $1, [ +#define _XOPEN_SOURCE_EXTENDED 1 +#include +/* The following two lines are a workaround against an autoconf-2.52 bug. */ +#include +#include +]) + fi + fi + ]) + case $gl_cv_header_errno_h_]$1[ in + yes | no) + ]$1[_HIDDEN=0; ]$1[_VALUE= + ;; + *) + ]$1[_HIDDEN=1; ]$1[_VALUE="$gl_cv_header_errno_h_]$1[" + ;; + esac + AC_SUBST($1[_HIDDEN]) + AC_SUBST($1[_VALUE]) + fi +]) + +dnl Autoconf >= 2.61 has AC_COMPUTE_INT built-in. +dnl Remove this when we can assume autoconf >= 2.61. +m4_ifdef([AC_COMPUTE_INT], [], [ + AC_DEFUN([AC_COMPUTE_INT], [_AC_COMPUTE_INT([$2],[$1],[$3],[$4])]) +]) diff --git a/m4/extensions.m4 b/m4/extensions.m4 index 611fcfdbc..ba6d5e190 100644 --- a/m4/extensions.m4 +++ b/m4/extensions.m4 @@ -1,7 +1,7 @@ -# serial 6 -*- Autoconf -*- +# serial 8 -*- Autoconf -*- # Enable extensions on systems that normally disable them. -# Copyright (C) 2003, 2006-2008 Free Software Foundation, Inc. +# Copyright (C) 2003, 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. @@ -20,7 +20,7 @@ # AC_DEFINE. The goal here is to define all known feature-enabling # macros, then, if reports of conflicts are made, disable macros that # cause problems on some platforms (such as __EXTENSIONS__). -AC_DEFUN([AC_USE_SYSTEM_EXTENSIONS], +AC_DEFUN_ONCE([AC_USE_SYSTEM_EXTENSIONS], [AC_BEFORE([$0], [AC_COMPILE_IFELSE])dnl AC_BEFORE([$0], [AC_RUN_IFELSE])dnl @@ -90,5 +90,15 @@ AC_BEFORE([$0], [AC_RUN_IFELSE])dnl # ------------------------ # Enable extensions on systems that normally disable them, # typically due to standards-conformance issues. -AC_DEFUN([gl_USE_SYSTEM_EXTENSIONS], - [AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])]) +AC_DEFUN_ONCE([gl_USE_SYSTEM_EXTENSIONS], +[ + dnl Require this macro before AC_USE_SYSTEM_EXTENSIONS. + dnl gnulib does not need it. But if it gets required by third-party macros + dnl after AC_USE_SYSTEM_EXTENSIONS is required, autoconf 2.62..2.63 emit a + dnl warning: "AC_COMPILE_IFELSE was called before AC_USE_SYSTEM_EXTENSIONS". + dnl Note: We can do this only for one of the macros AC_AIX, AC_GNU_SOURCE, + dnl AC_MINIX. If people still use AC_AIX or AC_MINIX, they are out of luck. + AC_REQUIRE([AC_GNU_SOURCE]) + + AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) +]) diff --git a/m4/float_h.m4 b/m4/float_h.m4 new file mode 100644 index 000000000..d36e3a46c --- /dev/null +++ b/m4/float_h.m4 @@ -0,0 +1,19 @@ +# float_h.m4 serial 3 +dnl Copyright (C) 2007 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FLOAT_H], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) + FLOAT_H= + case "$host_os" in + beos* | openbsd*) + FLOAT_H=float.h + gl_CHECK_NEXT_HEADERS([float.h]) + ;; + esac + AC_SUBST([FLOAT_H]) +]) diff --git a/m4/flock.m4 b/m4/flock.m4 new file mode 100644 index 000000000..96475fc57 --- /dev/null +++ b/m4/flock.m4 @@ -0,0 +1,26 @@ +# flock.m4 serial 1 +dnl Copyright (C) 2008 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_FLOCK], +[ + AC_REQUIRE([gl_HEADER_SYS_FILE_H_DEFAULTS]) + AC_CHECK_FUNCS_ONCE([flock]) + if test $ac_cv_func_flock = no; then + HAVE_FLOCK=0 + AC_LIBOBJ([flock]) + gl_PREREQ_FLOCK + fi +]) + +dnl Prerequisites of lib/flock.c. +AC_DEFUN([gl_PREREQ_FLOCK], +[ + AC_CHECK_FUNCS_ONCE([fcntl]) + AC_CHECK_HEADERS_ONCE([unistd.h fcntl.h]) + + dnl Do we have a POSIX fcntl lock implementation? + AC_CHECK_MEMBERS([struct flock.l_type],[],[],[[#include ]]) +]) diff --git a/m4/fpieee.m4 b/m4/fpieee.m4 new file mode 100644 index 000000000..9f4a92cb3 --- /dev/null +++ b/m4/fpieee.m4 @@ -0,0 +1,52 @@ +# fpieee.m4 serial 1 +dnl Copyright (C) 2007 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl IEEE 754 standardized three items: +dnl - The formats of single-float and double-float - nowadays commonly +dnl available as 'float' and 'double' in C and C++. +dnl No autoconf test needed. +dnl - The overflow and division by zero behaviour: The result are values +dnl '±Inf' and 'NaN', rather than exceptions as it was before. +dnl This file provides an autoconf macro for ensuring this behaviour of +dnl floating-point operations. +dnl - A set of conditions (overflow, underflow, inexact, etc.) which can +dnl be configured to trigger an exception. +dnl This cannot be done in a portable way: it depends on the compiler, +dnl libc, kernel, and CPU. No autoconf macro is provided for this. + +dnl Ensure non-trapping behaviour of floating-point overflow and +dnl floating-point division by zero. +dnl (For integer overflow, see gcc's -ftrapv option; for integer division by +dnl zero, see the autoconf macro in intdiv0.m4.) + +AC_DEFUN([gl_FP_IEEE], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) + # IEEE behaviour is the default on all CPUs except Alpha and SH + # (according to the test results of Bruno Haible's ieeefp/fenv_default.m4 + # and the GCC 4.1.2 manual). + case "$host_cpu" in + alpha*) + # On Alpha systems, a compiler option provides the behaviour. + # See the ieee(3) manual page, also available at + # + if test -n "$GCC"; then + # GCC has the option -mieee. + CPPFLAGS="$CPPFLAGS -mieee" + else + # Compaq (ex-DEC) C has the option -ieee. + CPPFLAGS="$CPPFLAGS -ieee" + fi + ;; + sh*) + if test -n "$GCC"; then + # GCC has the option -mieee. + CPPFLAGS="$CPPFLAGS -mieee" + fi + ;; + esac +]) diff --git a/m4/getpagesize.m4 b/m4/getpagesize.m4 new file mode 100644 index 000000000..0d07a3a53 --- /dev/null +++ b/m4/getpagesize.m4 @@ -0,0 +1,29 @@ +# getpagesize.m4 serial 7 +dnl Copyright (C) 2002, 2004-2005, 2007 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_GETPAGESIZE], +[ + AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_CHECK_FUNCS([getpagesize]) + if test $ac_cv_func_getpagesize = no; then + HAVE_GETPAGESIZE=0 + AC_CHECK_HEADERS([OS.h]) + if test $ac_cv_header_OS_h = yes; then + HAVE_OS_H=1 + fi + AC_CHECK_HEADERS([sys/param.h]) + if test $ac_cv_header_sys_param_h = yes; then + HAVE_SYS_PARAM_H=1 + fi + fi + case "$host_os" in + mingw*) + REPLACE_GETPAGESIZE=1 + AC_LIBOBJ([getpagesize]) + ;; + esac +]) diff --git a/m4/gnulib-cache.m4 b/m4/gnulib-cache.m4 index 2986b3cc4..b3a6d9996 100644 --- a/m4/gnulib-cache.m4 +++ b/m4/gnulib-cache.m4 @@ -15,18 +15,34 @@ # Specification in the form of a command-line invocation: -# gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --lgpl --libtool --macro-prefix=gl --no-vc-files alloca-opt autobuild extensions full-read full-write strcase strftime +# gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --lgpl --libtool --macro-prefix=gl --no-vc-files alloca-opt autobuild byteswap canonicalize-lgpl environ extensions flock fpieee full-read full-write havelib iconv_open-utf lib-symbol-versions lib-symbol-visibility libunistring putenv stdlib strcase strftime striconveh string verify vsnprintf # Specification in the form of a few gnulib-tool.m4 macro invocations: gl_LOCAL_DIR([]) gl_MODULES([ alloca-opt autobuild + byteswap + canonicalize-lgpl + environ extensions + flock + fpieee full-read full-write + havelib + iconv_open-utf + lib-symbol-versions + lib-symbol-visibility + libunistring + putenv + stdlib strcase strftime + striconveh + string + verify + vsnprintf ]) gl_AVOID([]) gl_SOURCE_BASE([lib]) diff --git a/m4/gnulib-common.m4 b/m4/gnulib-common.m4 index c73db14cc..c8fda2033 100644 --- a/m4/gnulib-common.m4 +++ b/m4/gnulib-common.m4 @@ -1,5 +1,5 @@ -# gnulib-common.m4 serial 6 -dnl Copyright (C) 2007-2008 Free Software Foundation, Inc. +# gnulib-common.m4 serial 11 +dnl Copyright (C) 2007-2009 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. @@ -8,6 +8,7 @@ dnl with or without modifications, as long as this notice is preserved. # is expanded unconditionally through gnulib-tool magic. AC_DEFUN([gl_COMMON], [ dnl Use AC_REQUIRE here, so that the code is expanded once only. + AC_REQUIRE([gl_00GNULIB]) AC_REQUIRE([gl_COMMON_BODY]) ]) AC_DEFUN([gl_COMMON_BODY], [ @@ -52,7 +53,7 @@ m4_ifndef([m4_foreach_w], # is a backport of autoconf-2.60's AC_PROG_MKDIR_P. # Remove this macro when we can assume autoconf >= 2.60. m4_ifdef([AC_PROG_MKDIR_P], [], [ - AC_DEFUN([AC_PROG_MKDIR_P], + AC_DEFUN_ONCE([AC_PROG_MKDIR_P], [AC_REQUIRE([AM_PROG_MKDIR_P])dnl defined by automake MKDIR_P='$(mkdir_p)' AC_SUBST([MKDIR_P])])]) @@ -63,7 +64,7 @@ m4_ifdef([AC_PROG_MKDIR_P], [], [ # works. # This definition can be removed once autoconf >= 2.62 can be assumed. AC_DEFUN([AC_C_RESTRICT], -[AC_CACHE_CHECK([for C/C++ restrict keyword], ac_cv_c_restrict, +[AC_CACHE_CHECK([for C/C++ restrict keyword], [ac_cv_c_restrict], [ac_cv_c_restrict=no # The order here caters to the fact that C++ does not require restrict. for ac_kw in __restrict __restrict__ _Restrict restrict; do @@ -99,3 +100,25 @@ AC_DEFUN([AC_C_RESTRICT], *) AC_DEFINE_UNQUOTED([restrict], [$ac_cv_c_restrict]) ;; esac ]) + +# gl_BIGENDIAN +# is like AC_C_BIGENDIAN, except that it can be AC_REQUIREd. +# Note that AC_REQUIRE([AC_C_BIGENDIAN]) does not work reliably because some +# macros invoke AC_C_BIGENDIAN with arguments. +AC_DEFUN([gl_BIGENDIAN], +[ + AC_C_BIGENDIAN +]) + +# gl_CACHE_VAL_SILENT(cache-id, command-to-set-it) +# is like AC_CACHE_VAL(cache-id, command-to-set-it), except that it does not +# output a spurious "(cached)" mark in the midst of other configure output. +# This macro should be used instead of AC_CACHE_VAL when it is not surrounded +# by an AC_MSG_CHECKING/AC_MSG_RESULT pair. +AC_DEFUN([gl_CACHE_VAL_SILENT], +[ + saved_as_echo_n="$as_echo_n" + as_echo_n=':' + AC_CACHE_VAL([$1], [$2]) + as_echo_n="$saved_as_echo_n" +]) diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4 index 327cdd022..1acdd40cd 100644 --- a/m4/gnulib-comp.m4 +++ b/m4/gnulib-comp.m4 @@ -15,7 +15,7 @@ # In projects using CVS, this file can be treated like other built files. -# This macro should be invoked from ./configure.in, in the section +# This macro should be invoked from ./configure.ac, in the section # "Checks for programs", right after AC_PROG_CC, and certainly before # any checks for libraries, header files, types and library functions. AC_DEFUN([gl_EARLY], @@ -25,11 +25,13 @@ AC_DEFUN([gl_EARLY], m4_pattern_allow([^gl_LIBOBJS$])dnl a variable m4_pattern_allow([^gl_LTLIBOBJS$])dnl a variable AC_REQUIRE([AC_PROG_RANLIB]) + AC_REQUIRE([AM_PROG_CC_C_O]) AB_INIT AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) + AC_REQUIRE([gl_FP_IEEE]) ]) -# This macro should be invoked from ./configure.in, in the section +# This macro should be invoked from ./configure.ac, in the section # "Check for header files, types and library functions". AC_DEFUN([gl_INIT], [ @@ -43,28 +45,77 @@ AC_DEFUN([gl_INIT], gl_COMMON gl_source_base='lib' gl_FUNC_ALLOCA + gl_BYTESWAP + gl_CANONICALIZE_LGPL + gl_MODULE_INDICATOR([canonicalize-lgpl]) + gl_ENVIRON + gl_UNISTD_MODULE_INDICATOR([environ]) + gl_HEADER_ERRNO_H + gl_FLOAT_H + gl_FUNC_FLOCK + gl_HEADER_SYS_FILE_MODULE_INDICATOR([flock]) + gl_FUNC_GETPAGESIZE + gl_UNISTD_MODULE_INDICATOR([getpagesize]) + AM_ICONV + gl_ICONV_H + gl_FUNC_ICONV_OPEN + gl_FUNC_ICONV_OPEN_UTF + gl_INLINE + gl_LD_VERSION_SCRIPT + gl_VISIBILITY + gl_LIBUNISTRING gl_LOCALCHARSET LOCALCHARSET_TESTS_ENVIRONMENT="CHARSETALIASDIR=\"\$(top_builddir)/$gl_source_base\"" AC_SUBST([LOCALCHARSET_TESTS_ENVIRONMENT]) + gl_FUNC_MALLOC_POSIX + gl_STDLIB_MODULE_INDICATOR([malloc-posix]) + gl_MALLOCA gl_FUNC_MBRLEN gl_WCHAR_MODULE_INDICATOR([mbrlen]) gl_FUNC_MBRTOWC gl_WCHAR_MODULE_INDICATOR([mbrtowc]) gl_FUNC_MBSINIT gl_WCHAR_MODULE_INDICATOR([mbsinit]) + gl_FUNC_MEMCHR + gl_STRING_MODULE_INDICATOR([memchr]) + gl_MULTIARCH + gl_PATHMAX + gl_FUNC_PUTENV + gl_STDLIB_MODULE_INDICATOR([putenv]) + gl_FUNC_READLINK + gl_UNISTD_MODULE_INDICATOR([readlink]) gl_SAFE_READ gl_SAFE_WRITE + gl_SIZE_MAX gt_TYPE_SSIZE_T AM_STDBOOL_H + gl_STDINT_H + gl_STDIO_H + gl_STDLIB_H gl_STRCASE gl_FUNC_GNU_STRFTIME + if test $gl_cond_libtool = false; then + gl_ltlibdeps="$gl_ltlibdeps $LTLIBICONV" + gl_libdeps="$gl_libdeps $LIBICONV" + fi + gl_HEADER_STRING_H gl_HEADER_STRINGS_H + gl_HEADER_SYS_FILE_H + AC_PROG_MKDIR_P gl_HEADER_TIME_H gl_TIME_R gl_UNISTD_H + gl_MODULE_INDICATOR([unistr/u8-mbtouc]) + gl_MODULE_INDICATOR([unistr/u8-mbtouc-unsafe]) + gl_MODULE_INDICATOR([unistr/u8-mbtoucr]) + gl_MODULE_INDICATOR([unistr/u8-uctomb]) + gl_FUNC_VASNPRINTF + gl_FUNC_VSNPRINTF + gl_STDIO_MODULE_INDICATOR([vsnprintf]) gl_WCHAR_H gl_FUNC_WRITE gl_UNISTD_MODULE_INDICATOR([write]) + gl_XSIZE m4_ifval(gl_LIBSOURCES_LIST, [ m4_syscmd([test ! -d ]m4_defn([gl_LIBSOURCES_DIR])[ || for gl_file in ]gl_LIBSOURCES_LIST[ ; do @@ -193,64 +244,168 @@ AC_DEFUN([gltests_LIBSOURCES], [ # This macro records the list of files which have been installed by # gnulib-tool and may be removed by future gnulib-tool invocations. AC_DEFUN([gl_FILE_LIST], [ + build-aux/config.rpath build-aux/link-warning.h lib/alloca.in.h + lib/asnprintf.c + lib/byteswap.in.h + lib/c-ctype.c + lib/c-ctype.h + lib/c-strcase.h + lib/c-strcasecmp.c + lib/c-strcaseeq.h + lib/c-strncasecmp.c + lib/canonicalize-lgpl.c + lib/canonicalize.h lib/config.charset + lib/errno.in.h + lib/float+.h + lib/float.in.h + lib/flock.c lib/full-read.c lib/full-read.h lib/full-write.c lib/full-write.h + lib/getpagesize.c + lib/iconv.c + lib/iconv.in.h + lib/iconv_close.c + lib/iconv_open-aix.gperf + lib/iconv_open-hpux.gperf + lib/iconv_open-irix.gperf + lib/iconv_open-osf.gperf + lib/iconv_open.c + lib/iconveh.h lib/localcharset.c lib/localcharset.h + lib/malloc.c + lib/malloca.c + lib/malloca.h + lib/malloca.valgrind lib/mbrlen.c lib/mbrtowc.c lib/mbsinit.c + lib/memchr.c + lib/memchr.valgrind + lib/pathmax.h + lib/printf-args.c + lib/printf-args.h + lib/printf-parse.c + lib/printf-parse.h + lib/putenv.c + lib/readlink.c lib/ref-add.sin lib/ref-del.sin lib/safe-read.c lib/safe-read.h lib/safe-write.c lib/safe-write.h + lib/size_max.h lib/stdbool.in.h + lib/stdint.in.h + lib/stdio-write.c + lib/stdio.in.h + lib/stdlib.in.h lib/strcasecmp.c lib/streq.h lib/strftime.c lib/strftime.h + lib/striconveh.c + lib/striconveh.h + lib/string.in.h lib/strings.in.h lib/strncasecmp.c + lib/sys_file.in.h lib/time.in.h lib/time_r.c lib/unistd.in.h + lib/unistr.h + lib/unistr/u8-mbtouc-aux.c + lib/unistr/u8-mbtouc-unsafe-aux.c + lib/unistr/u8-mbtouc-unsafe.c + lib/unistr/u8-mbtouc.c + lib/unistr/u8-mbtoucr.c + lib/unistr/u8-prev.c + lib/unistr/u8-uctomb-aux.c + lib/unistr/u8-uctomb.c + lib/unitypes.h + lib/vasnprintf.c + lib/vasnprintf.h lib/verify.h + lib/vsnprintf.c lib/wchar.in.h lib/write.c + lib/xsize.h + m4/00gnulib.m4 m4/alloca.m4 m4/autobuild.m4 + m4/byteswap.m4 + m4/canonicalize-lgpl.m4 m4/codeset.m4 + m4/eealloc.m4 + m4/environ.m4 + m4/errno_h.m4 m4/extensions.m4 + m4/float_h.m4 + m4/flock.m4 + m4/fpieee.m4 + m4/getpagesize.m4 m4/glibc21.m4 m4/gnulib-common.m4 + m4/iconv.m4 + m4/iconv_h.m4 + m4/iconv_open.m4 m4/include_next.m4 + m4/inline.m4 + m4/intmax_t.m4 + m4/inttypes_h.m4 + m4/ld-version-script.m4 + m4/lib-ld.m4 + m4/lib-link.m4 + m4/lib-prefix.m4 + m4/libunistring.m4 m4/localcharset.m4 m4/locale-fr.m4 m4/locale-ja.m4 m4/locale-zh.m4 + m4/longlong.m4 + m4/malloc.m4 + m4/malloca.m4 m4/mbrlen.m4 m4/mbrtowc.m4 m4/mbsinit.m4 m4/mbstate_t.m4 + m4/memchr.m4 + m4/mmap-anon.m4 + m4/multiarch.m4 + m4/pathmax.m4 + m4/printf.m4 + m4/putenv.m4 + m4/readlink.m4 m4/safe-read.m4 m4/safe-write.m4 + m4/size_max.m4 m4/ssize_t.m4 m4/stdbool.m4 + m4/stdint.m4 + m4/stdint_h.m4 + m4/stdio_h.m4 + m4/stdlib_h.m4 m4/strcase.m4 m4/strftime.m4 + m4/string_h.m4 m4/strings_h.m4 + m4/sys_file_h.m4 m4/time_h.m4 m4/time_r.m4 m4/tm_gmtoff.m4 m4/unistd_h.m4 + m4/vasnprintf.m4 + m4/visibility.m4 + m4/vsnprintf.m4 m4/wchar.m4 + m4/wchar_t.m4 m4/wint_t.m4 m4/write.m4 + m4/xsize.m4 ]) diff --git a/m4/iconv.m4 b/m4/iconv.m4 new file mode 100644 index 000000000..ce21b0b87 --- /dev/null +++ b/m4/iconv.m4 @@ -0,0 +1,180 @@ +# iconv.m4 serial AM8 (gettext-0.18) +dnl Copyright (C) 2000-2002, 2007-2009 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. + +AC_DEFUN([AM_ICONV_LINKFLAGS_BODY], +[ + dnl Prerequisites of AC_LIB_LINKFLAGS_BODY. + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + AC_REQUIRE([AC_LIB_RPATH]) + + dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV + dnl accordingly. + AC_LIB_LINKFLAGS_BODY([iconv]) +]) + +AC_DEFUN([AM_ICONV_LINK], +[ + dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and + dnl those with the standalone portable GNU libiconv installed). + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + + dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV + dnl accordingly. + AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY]) + + dnl Add $INCICONV to CPPFLAGS before performing the following checks, + dnl because if the user has installed libiconv and not disabled its use + dnl via --without-libiconv-prefix, he wants to use it. The first + dnl AC_TRY_LINK will then fail, the second AC_TRY_LINK will succeed. + am_save_CPPFLAGS="$CPPFLAGS" + AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCICONV]) + + AC_CACHE_CHECK([for iconv], [am_cv_func_iconv], [ + am_cv_func_iconv="no, consider installing GNU libiconv" + am_cv_lib_iconv=no + AC_TRY_LINK([#include +#include ], + [iconv_t cd = iconv_open("",""); + iconv(cd,NULL,NULL,NULL,NULL); + iconv_close(cd);], + [am_cv_func_iconv=yes]) + if test "$am_cv_func_iconv" != yes; then + am_save_LIBS="$LIBS" + LIBS="$LIBS $LIBICONV" + AC_TRY_LINK([#include +#include ], + [iconv_t cd = iconv_open("",""); + iconv(cd,NULL,NULL,NULL,NULL); + iconv_close(cd);], + [am_cv_lib_iconv=yes] + [am_cv_func_iconv=yes]) + LIBS="$am_save_LIBS" + fi + ]) + if test "$am_cv_func_iconv" = yes; then + AC_CACHE_CHECK([for working iconv], [am_cv_func_iconv_works], [ + dnl This tests against bugs in AIX 5.1 and HP-UX 11.11. + am_save_LIBS="$LIBS" + if test $am_cv_lib_iconv = yes; then + LIBS="$LIBS $LIBICONV" + fi + AC_TRY_RUN([ +#include +#include +int main () +{ + /* Test against AIX 5.1 bug: Failures are not distinguishable from successful + returns. */ + { + iconv_t cd_utf8_to_88591 = iconv_open ("ISO8859-1", "UTF-8"); + if (cd_utf8_to_88591 != (iconv_t)(-1)) + { + static const char input[] = "\342\202\254"; /* EURO SIGN */ + char buf[10]; + const char *inptr = input; + size_t inbytesleft = strlen (input); + char *outptr = buf; + size_t outbytesleft = sizeof (buf); + size_t res = iconv (cd_utf8_to_88591, + (char **) &inptr, &inbytesleft, + &outptr, &outbytesleft); + if (res == 0) + return 1; + } + } +#if 0 /* This bug could be worked around by the caller. */ + /* Test against HP-UX 11.11 bug: Positive return value instead of 0. */ + { + iconv_t cd_88591_to_utf8 = iconv_open ("utf8", "iso88591"); + if (cd_88591_to_utf8 != (iconv_t)(-1)) + { + static const char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337"; + char buf[50]; + const char *inptr = input; + size_t inbytesleft = strlen (input); + char *outptr = buf; + size_t outbytesleft = sizeof (buf); + size_t res = iconv (cd_88591_to_utf8, + (char **) &inptr, &inbytesleft, + &outptr, &outbytesleft); + if ((int)res > 0) + return 1; + } + } +#endif + /* Test against HP-UX 11.11 bug: No converter from EUC-JP to UTF-8 is + provided. */ + if (/* Try standardized names. */ + iconv_open ("UTF-8", "EUC-JP") == (iconv_t)(-1) + /* Try IRIX, OSF/1 names. */ + && iconv_open ("UTF-8", "eucJP") == (iconv_t)(-1) + /* Try AIX names. */ + && iconv_open ("UTF-8", "IBM-eucJP") == (iconv_t)(-1) + /* Try HP-UX names. */ + && iconv_open ("utf8", "eucJP") == (iconv_t)(-1)) + return 1; + return 0; +}], [am_cv_func_iconv_works=yes], [am_cv_func_iconv_works=no], + [case "$host_os" in + aix* | hpux*) am_cv_func_iconv_works="guessing no" ;; + *) am_cv_func_iconv_works="guessing yes" ;; + esac]) + LIBS="$am_save_LIBS" + ]) + case "$am_cv_func_iconv_works" in + *no) am_func_iconv=no am_cv_lib_iconv=no ;; + *) am_func_iconv=yes ;; + esac + else + am_func_iconv=no am_cv_lib_iconv=no + fi + if test "$am_func_iconv" = yes; then + AC_DEFINE([HAVE_ICONV], [1], + [Define if you have the iconv() function and it works.]) + fi + if test "$am_cv_lib_iconv" = yes; then + AC_MSG_CHECKING([how to link with libiconv]) + AC_MSG_RESULT([$LIBICONV]) + else + dnl If $LIBICONV didn't lead to a usable library, we don't need $INCICONV + dnl either. + CPPFLAGS="$am_save_CPPFLAGS" + LIBICONV= + LTLIBICONV= + fi + AC_SUBST([LIBICONV]) + AC_SUBST([LTLIBICONV]) +]) + +AC_DEFUN([AM_ICONV], +[ + AM_ICONV_LINK + if test "$am_cv_func_iconv" = yes; then + AC_MSG_CHECKING([for iconv declaration]) + AC_CACHE_VAL([am_cv_proto_iconv], [ + AC_TRY_COMPILE([ +#include +#include +extern +#ifdef __cplusplus +"C" +#endif +#if defined(__STDC__) || defined(__cplusplus) +size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); +#else +size_t iconv(); +#endif +], [], [am_cv_proto_iconv_arg1=""], [am_cv_proto_iconv_arg1="const"]) + am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"]) + am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'` + AC_MSG_RESULT([ + $am_cv_proto_iconv]) + AC_DEFINE_UNQUOTED([ICONV_CONST], [$am_cv_proto_iconv_arg1], + [Define as const if the declaration of iconv() needs const.]) + fi +]) diff --git a/m4/iconv_h.m4 b/m4/iconv_h.m4 new file mode 100644 index 000000000..bc05b0551 --- /dev/null +++ b/m4/iconv_h.m4 @@ -0,0 +1,34 @@ +# iconv_h.m4 serial 4 +dnl Copyright (C) 2007-2008 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_ICONV_H], +[ + AC_REQUIRE([gl_ICONV_H_DEFAULTS]) + gl_CHECK_NEXT_HEADERS([iconv.h]) +]) + +dnl Unconditionally enables the replacement of . +AC_DEFUN([gl_REPLACE_ICONV_H], +[ + AC_REQUIRE([gl_ICONV_H_DEFAULTS]) + ICONV_H='iconv.h' +]) + +AC_DEFUN([gl_ICONV_MODULE_INDICATOR], +[ + dnl Use AC_REQUIRE here, so that the default settings are expanded once only. + AC_REQUIRE([gl_ICONV_H_DEFAULTS]) + GNULIB_[]m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./-],[ABCDEFGHIJKLMNOPQRSTUVWXYZ___])=1 +]) + +AC_DEFUN([gl_ICONV_H_DEFAULTS], +[ + dnl Assume proper GNU behavior unless another module says otherwise. + REPLACE_ICONV=0; AC_SUBST([REPLACE_ICONV]) + REPLACE_ICONV_OPEN=0; AC_SUBST([REPLACE_ICONV_OPEN]) + REPLACE_ICONV_UTF=0; AC_SUBST([REPLACE_ICONV_UTF]) + ICONV_H=''; AC_SUBST([ICONV_H]) +]) diff --git a/m4/iconv_open.m4 b/m4/iconv_open.m4 new file mode 100644 index 000000000..c7b948e90 --- /dev/null +++ b/m4/iconv_open.m4 @@ -0,0 +1,237 @@ +# iconv_open.m4 serial 5 +dnl Copyright (C) 2007-2009 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_ICONV_OPEN], +[ + AC_REQUIRE([AM_ICONV]) + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_REQUIRE([gl_ICONV_H_DEFAULTS]) + if test "$am_cv_func_iconv" = yes; then + dnl Test whether iconv_open accepts standardized encoding names. + dnl We know that GNU libiconv and GNU libc do. + AC_EGREP_CPP([gnu_iconv], [ + #include + #if defined _LIBICONV_VERSION || defined __GLIBC__ + gnu_iconv + #endif + ], [gl_func_iconv_gnu=yes], [gl_func_iconv_gnu=no]) + if test $gl_func_iconv_gnu = no; then + iconv_flavor= + case "$host_os" in + aix*) iconv_flavor=ICONV_FLAVOR_AIX ;; + irix*) iconv_flavor=ICONV_FLAVOR_IRIX ;; + hpux*) iconv_flavor=ICONV_FLAVOR_HPUX ;; + osf*) iconv_flavor=ICONV_FLAVOR_OSF ;; + esac + if test -n "$iconv_flavor"; then + AC_DEFINE_UNQUOTED([ICONV_FLAVOR], [$iconv_flavor], + [Define to a symbolic name denoting the flavor of iconv_open() + implementation.]) + gl_REPLACE_ICONV_OPEN + fi + fi + fi +]) + +AC_DEFUN([gl_REPLACE_ICONV_OPEN], +[ + gl_REPLACE_ICONV_H + REPLACE_ICONV_OPEN=1 + AC_LIBOBJ([iconv_open]) +]) + +AC_DEFUN([gl_FUNC_ICONV_OPEN_UTF], +[ + AC_REQUIRE([gl_FUNC_ICONV_OPEN]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_REQUIRE([gl_ICONV_H_DEFAULTS]) + if test "$am_cv_func_iconv" = yes; then + if test -n "$am_cv_proto_iconv_arg1"; then + ICONV_CONST="const" + else + ICONV_CONST= + fi + AC_SUBST([ICONV_CONST]) + AC_CACHE_CHECK([whether iconv supports conversion between UTF-8 and UTF-{16,32}{BE,LE}], + [gl_cv_func_iconv_supports_utf], + [ + save_LIBS="$LIBS" + LIBS="$LIBS $LIBICONV" + AC_TRY_RUN([ +#include +#include +#include +#include +#include +#define ASSERT(expr) if (!(expr)) return 1; +int main () +{ + /* Test conversion from UTF-8 to UTF-16BE with no errors. */ + { + static const char input[] = + "Japanese (\346\227\245\346\234\254\350\252\236) [\360\235\224\215\360\235\224\236\360\235\224\255]"; + static const char expected[] = + "\000J\000a\000p\000a\000n\000e\000s\000e\000 \000(\145\345\147\054\212\236\000)\000 \000[\330\065\335\015\330\065\335\036\330\065\335\055\000]"; + iconv_t cd; + char buf[100]; + const char *inptr; + size_t inbytesleft; + char *outptr; + size_t outbytesleft; + size_t res; + cd = iconv_open ("UTF-16BE", "UTF-8"); + ASSERT (cd != (iconv_t)(-1)); + inptr = input; + inbytesleft = sizeof (input) - 1; + outptr = buf; + outbytesleft = sizeof (buf); + res = iconv (cd, + (ICONV_CONST char **) &inptr, &inbytesleft, + &outptr, &outbytesleft); + ASSERT (res == 0 && inbytesleft == 0); + ASSERT (outptr == buf + (sizeof (expected) - 1)); + ASSERT (memcmp (buf, expected, sizeof (expected) - 1) == 0); + ASSERT (iconv_close (cd) == 0); + } + /* Test conversion from UTF-8 to UTF-16LE with no errors. */ + { + static const char input[] = + "Japanese (\346\227\245\346\234\254\350\252\236) [\360\235\224\215\360\235\224\236\360\235\224\255]"; + static const char expected[] = + "J\000a\000p\000a\000n\000e\000s\000e\000 \000(\000\345\145\054\147\236\212)\000 \000[\000\065\330\015\335\065\330\036\335\065\330\055\335]\000"; + iconv_t cd; + char buf[100]; + const char *inptr; + size_t inbytesleft; + char *outptr; + size_t outbytesleft; + size_t res; + cd = iconv_open ("UTF-16LE", "UTF-8"); + ASSERT (cd != (iconv_t)(-1)); + inptr = input; + inbytesleft = sizeof (input) - 1; + outptr = buf; + outbytesleft = sizeof (buf); + res = iconv (cd, + (ICONV_CONST char **) &inptr, &inbytesleft, + &outptr, &outbytesleft); + ASSERT (res == 0 && inbytesleft == 0); + ASSERT (outptr == buf + (sizeof (expected) - 1)); + ASSERT (memcmp (buf, expected, sizeof (expected) - 1) == 0); + ASSERT (iconv_close (cd) == 0); + } + /* Test conversion from UTF-8 to UTF-32BE with no errors. */ + { + static const char input[] = + "Japanese (\346\227\245\346\234\254\350\252\236) [\360\235\224\215\360\235\224\236\360\235\224\255]"; + static const char expected[] = + "\000\000\000J\000\000\000a\000\000\000p\000\000\000a\000\000\000n\000\000\000e\000\000\000s\000\000\000e\000\000\000 \000\000\000(\000\000\145\345\000\000\147\054\000\000\212\236\000\000\000)\000\000\000 \000\000\000[\000\001\325\015\000\001\325\036\000\001\325\055\000\000\000]"; + iconv_t cd; + char buf[100]; + const char *inptr; + size_t inbytesleft; + char *outptr; + size_t outbytesleft; + size_t res; + cd = iconv_open ("UTF-32BE", "UTF-8"); + ASSERT (cd != (iconv_t)(-1)); + inptr = input; + inbytesleft = sizeof (input) - 1; + outptr = buf; + outbytesleft = sizeof (buf); + res = iconv (cd, + (ICONV_CONST char **) &inptr, &inbytesleft, + &outptr, &outbytesleft); + ASSERT (res == 0 && inbytesleft == 0); + ASSERT (outptr == buf + (sizeof (expected) - 1)); + ASSERT (memcmp (buf, expected, sizeof (expected) - 1) == 0); + ASSERT (iconv_close (cd) == 0); + } + /* Test conversion from UTF-8 to UTF-32LE with no errors. */ + { + static const char input[] = + "Japanese (\346\227\245\346\234\254\350\252\236) [\360\235\224\215\360\235\224\236\360\235\224\255]"; + static const char expected[] = + "J\000\000\000a\000\000\000p\000\000\000a\000\000\000n\000\000\000e\000\000\000s\000\000\000e\000\000\000 \000\000\000(\000\000\000\345\145\000\000\054\147\000\000\236\212\000\000)\000\000\000 \000\000\000[\000\000\000\015\325\001\000\036\325\001\000\055\325\001\000]\000\000\000"; + iconv_t cd; + char buf[100]; + const char *inptr; + size_t inbytesleft; + char *outptr; + size_t outbytesleft; + size_t res; + cd = iconv_open ("UTF-32LE", "UTF-8"); + ASSERT (cd != (iconv_t)(-1)); + inptr = input; + inbytesleft = sizeof (input) - 1; + outptr = buf; + outbytesleft = sizeof (buf); + res = iconv (cd, + (ICONV_CONST char **) &inptr, &inbytesleft, + &outptr, &outbytesleft); + ASSERT (res == 0 && inbytesleft == 0); + ASSERT (outptr == buf + (sizeof (expected) - 1)); + ASSERT (memcmp (buf, expected, sizeof (expected) - 1) == 0); + ASSERT (iconv_close (cd) == 0); + } + /* Test conversion from UTF-16BE to UTF-8 with no errors. + This test fails on NetBSD 3.0. */ + { + static const char input[] = + "\000J\000a\000p\000a\000n\000e\000s\000e\000 \000(\145\345\147\054\212\236\000)\000 \000[\330\065\335\015\330\065\335\036\330\065\335\055\000]"; + static const char expected[] = + "Japanese (\346\227\245\346\234\254\350\252\236) [\360\235\224\215\360\235\224\236\360\235\224\255]"; + iconv_t cd; + char buf[100]; + const char *inptr; + size_t inbytesleft; + char *outptr; + size_t outbytesleft; + size_t res; + cd = iconv_open ("UTF-8", "UTF-16BE"); + ASSERT (cd != (iconv_t)(-1)); + inptr = input; + inbytesleft = sizeof (input) - 1; + outptr = buf; + outbytesleft = sizeof (buf); + res = iconv (cd, + (ICONV_CONST char **) &inptr, &inbytesleft, + &outptr, &outbytesleft); + ASSERT (res == 0 && inbytesleft == 0); + ASSERT (outptr == buf + (sizeof (expected) - 1)); + ASSERT (memcmp (buf, expected, sizeof (expected) - 1) == 0); + ASSERT (iconv_close (cd) == 0); + } + return 0; +}], [gl_cv_func_iconv_supports_utf=yes], [gl_cv_func_iconv_supports_utf=no], + [ + dnl We know that GNU libiconv, GNU libc, and Solaris >= 9 do. + dnl OSF/1 5.1 has these encodings, but inserts a BOM in the "to" + dnl direction. + gl_cv_func_iconv_supports_utf=no + if test $gl_func_iconv_gnu = yes; then + gl_cv_func_iconv_supports_utf=yes + else +changequote(,)dnl + case "$host_os" in + solaris2.9 | solaris2.1[0-9]) gl_cv_func_iconv_supports_utf=yes ;; + esac +changequote([,])dnl + fi + ]) + LIBS="$save_LIBS" + ]) + if test $gl_cv_func_iconv_supports_utf = no; then + REPLACE_ICONV_UTF=1 + AC_DEFINE([REPLACE_ICONV_UTF], [1], + [Define if the iconv() functions are enhanced to handle the UTF-{16,32}{BE,LE} encodings.]) + REPLACE_ICONV=1 + gl_REPLACE_ICONV_OPEN + AC_LIBOBJ([iconv]) + AC_LIBOBJ([iconv_close]) + fi + fi +]) diff --git a/m4/include_next.m4 b/m4/include_next.m4 index 062753c58..5e22ded93 100644 --- a/m4/include_next.m4 +++ b/m4/include_next.m4 @@ -1,5 +1,5 @@ -# include_next.m4 serial 10 -dnl Copyright (C) 2006-2008 Free Software Foundation, Inc. +# include_next.m4 serial 14 +dnl Copyright (C) 2006-2009 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. @@ -32,14 +32,15 @@ AC_DEFUN([gl_INCLUDE_NEXT], [gl_cv_have_include_next], [rm -rf conftestd1a conftestd1b conftestd2 mkdir conftestd1a conftestd1b conftestd2 - dnl The include of is because IBM C 9.0 on AIX 6.1 supports - dnl include_next when used as first preprocessor directive in a file, - dnl but not when preceded by another include directive. Additionally, - dnl with this same compiler, include_next is a no-op when used in a - dnl header file that was included by specifying its absolute file name. - dnl Despite these two bugs, include_next is used in the compiler's - dnl . By virtue of the second bug, we need to use include_next - dnl as well in this case. + dnl IBM C 9.0, 10.1 (original versions, prior to the 2009-01 updates) on + dnl AIX 6.1 support include_next when used as first preprocessor directive + dnl in a file, but not when preceded by another include directive. Check + dnl for this bug by including . + dnl Additionally, with this same compiler, include_next is a no-op when + dnl used in a header file that was included by specifying its absolute + dnl file name. Despite these two bugs, include_next is used in the + dnl compiler's . By virtue of the second bug, we need to use + dnl include_next as well in this case. cat < conftestd1a/conftest.h #define DEFINED_IN_CONFTESTD1 #include_next @@ -103,8 +104,14 @@ EOF # For each arg foo.h, if #include_next works, define NEXT_FOO_H to be # ''; otherwise define it to be # '"///usr/include/foo.h"', or whatever other absolute file name is suitable. +# Also, if #include_next works as first preprocessing directive in a file, +# define NEXT_AS_FIRST_DIRECTIVE_FOO_H to be ''; otherwise define it to +# be +# '"///usr/include/foo.h"', or whatever other absolute file name is suitable. # That way, a header file with the following line: # #@INCLUDE_NEXT@ @NEXT_FOO_H@ +# or +# #@INCLUDE_NEXT_AS_FIRST_DIRECTIVE@ @NEXT_AS_FIRST_DIRECTIVE_FOO_H@ # behaves (after sed substitution) as if it contained # #include_next # even if the compiler does not support include_next. @@ -122,15 +129,15 @@ AC_DEFUN([gl_CHECK_NEXT_HEADERS], m4_foreach_w([gl_HEADER_NAME], [$1], [AS_VAR_PUSHDEF([gl_next_header], - [gl_cv_next_]m4_quote(m4_defn([gl_HEADER_NAME]))) + [gl_cv_next_]m4_defn([gl_HEADER_NAME])) if test $gl_cv_have_include_next = yes; then AS_VAR_SET([gl_next_header], ['<'gl_HEADER_NAME'>']) else AC_CACHE_CHECK( - [absolute name of <]m4_quote(m4_defn([gl_HEADER_NAME]))[>], - m4_quote(m4_defn([gl_next_header])), + [absolute name of <]m4_defn([gl_HEADER_NAME])[>], + m4_defn([gl_next_header]), [AS_VAR_PUSHDEF([gl_header_exists], - [ac_cv_header_]m4_quote(m4_defn([gl_HEADER_NAME]))) + [ac_cv_header_]m4_defn([gl_HEADER_NAME])) if test AS_VAR_GET(gl_header_exists) = yes; then AC_LANG_CONFTEST( [AC_LANG_SOURCE( @@ -152,8 +159,8 @@ AC_DEFUN([gl_CHECK_NEXT_HEADERS], dnl so use subshell. AS_VAR_SET([gl_next_header], ['"'`(eval "$gl_absname_cpp conftest.$ac_ext") 2>&AS_MESSAGE_LOG_FD | - sed -n '\#/]m4_quote(m4_defn([gl_HEADER_NAME]))[#{ - s#.*"\(.*/]m4_quote(m4_defn([gl_HEADER_NAME]))[\)".*#\1# + sed -n '\#/]m4_defn([gl_HEADER_NAME])[#{ + s#.*"\(.*/]m4_defn([gl_HEADER_NAME])[\)".*#\1# s#^/[^/]#//&# p q @@ -164,7 +171,17 @@ AC_DEFUN([gl_CHECK_NEXT_HEADERS], AS_VAR_POPDEF([gl_header_exists])]) fi AC_SUBST( - AS_TR_CPP([NEXT_]m4_quote(m4_defn([gl_HEADER_NAME]))), + AS_TR_CPP([NEXT_]m4_defn([gl_HEADER_NAME])), [AS_VAR_GET([gl_next_header])]) + if test $gl_cv_have_include_next = yes || test $gl_cv_have_include_next = buggy; then + # INCLUDE_NEXT_AS_FIRST_DIRECTIVE='include_next' + gl_next_as_first_directive='<'gl_HEADER_NAME'>' + else + # INCLUDE_NEXT_AS_FIRST_DIRECTIVE='include' + gl_next_as_first_directive=AS_VAR_GET([gl_next_header]) + fi + AC_SUBST( + AS_TR_CPP([NEXT_AS_FIRST_DIRECTIVE_]m4_defn([gl_HEADER_NAME])), + [$gl_next_as_first_directive]) AS_VAR_POPDEF([gl_next_header])]) ]) diff --git a/m4/inline.m4 b/m4/inline.m4 new file mode 100644 index 000000000..cee51099f --- /dev/null +++ b/m4/inline.m4 @@ -0,0 +1,40 @@ +# inline.m4 serial 4 +dnl Copyright (C) 2006, 2009 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl Test for the 'inline' keyword or equivalent. +dnl Define 'inline' to a supported equivalent, or to nothing if not supported, +dnl like AC_C_INLINE does. Also, define HAVE_INLINE if 'inline' or an +dnl equivalent is effectively supported, i.e. if the compiler is likely to +dnl drop unused 'static inline' functions. +AC_DEFUN([gl_INLINE], +[ + AC_REQUIRE([AC_C_INLINE]) + AC_CACHE_CHECK([whether the compiler generally respects inline], + [gl_cv_c_inline_effective], + [if test $ac_cv_c_inline = no; then + gl_cv_c_inline_effective=no + else + dnl GCC defines __NO_INLINE__ if not optimizing or if -fno-inline is + dnl specified. + dnl Use AC_COMPILE_IFELSE here, not AC_EGREP_CPP, because the result + dnl depends on optimization flags, which can be in CFLAGS. + dnl (AC_EGREP_CPP looks only at the CPPFLAGS.) + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[]], + [[#ifdef __NO_INLINE__ + #error "inline is not effective" + #endif]])], + [gl_cv_c_inline_effective=yes], + [gl_cv_c_inline_effective=no]) + fi + ]) + if test $gl_cv_c_inline_effective = yes; then + AC_DEFINE([HAVE_INLINE], [1], + [Define to 1 if the compiler supports one of the keywords + 'inline', '__inline__', '__inline' and effectively inlines + functions marked as such.]) + fi +]) diff --git a/m4/intmax_t.m4 b/m4/intmax_t.m4 new file mode 100644 index 000000000..264cb5718 --- /dev/null +++ b/m4/intmax_t.m4 @@ -0,0 +1,61 @@ +# intmax_t.m4 serial 7 +dnl Copyright (C) 1997-2004, 2006-2007, 2009 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Paul Eggert. + +AC_PREREQ([2.13]) + +# Define intmax_t to 'long' or 'long long' +# if it is not already defined in or . + +AC_DEFUN([gl_AC_TYPE_INTMAX_T], +[ + dnl For simplicity, we assume that a header file defines 'intmax_t' if and + dnl only if it defines 'uintmax_t'. + AC_REQUIRE([gl_AC_HEADER_INTTYPES_H]) + AC_REQUIRE([gl_AC_HEADER_STDINT_H]) + if test $gl_cv_header_inttypes_h = no && test $gl_cv_header_stdint_h = no; then + AC_REQUIRE([AC_TYPE_LONG_LONG_INT]) + test $ac_cv_type_long_long_int = yes \ + && ac_type='long long' \ + || ac_type='long' + AC_DEFINE_UNQUOTED([intmax_t], [$ac_type], + [Define to long or long long if and don't define.]) + else + AC_DEFINE([HAVE_INTMAX_T], [1], + [Define if you have the 'intmax_t' type in or .]) + fi +]) + +dnl An alternative would be to explicitly test for 'intmax_t'. + +AC_DEFUN([gt_AC_TYPE_INTMAX_T], +[ + AC_REQUIRE([gl_AC_HEADER_INTTYPES_H]) + AC_REQUIRE([gl_AC_HEADER_STDINT_H]) + AC_CACHE_CHECK([for intmax_t], [gt_cv_c_intmax_t], + [AC_TRY_COMPILE([ +#include +#include +#if HAVE_STDINT_H_WITH_UINTMAX +#include +#endif +#if HAVE_INTTYPES_H_WITH_UINTMAX +#include +#endif +], [intmax_t x = -1; return !x;], gt_cv_c_intmax_t=yes, gt_cv_c_intmax_t=no)]) + if test $gt_cv_c_intmax_t = yes; then + AC_DEFINE([HAVE_INTMAX_T], [1], + [Define if you have the 'intmax_t' type in or .]) + else + AC_REQUIRE([AC_TYPE_LONG_LONG_INT]) + test $ac_cv_type_long_long_int = yes \ + && ac_type='long long' \ + || ac_type='long' + AC_DEFINE_UNQUOTED([intmax_t], [$ac_type], + [Define to long or long long if and don't define.]) + fi +]) diff --git a/m4/inttypes_h.m4 b/m4/inttypes_h.m4 new file mode 100644 index 000000000..f4ca16021 --- /dev/null +++ b/m4/inttypes_h.m4 @@ -0,0 +1,26 @@ +# inttypes_h.m4 serial 9 +dnl Copyright (C) 1997-2004, 2006, 2008, 2009 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Paul Eggert. + +# Define HAVE_INTTYPES_H_WITH_UINTMAX if exists, +# doesn't clash with , and declares uintmax_t. + +AC_DEFUN([gl_AC_HEADER_INTTYPES_H], +[ + AC_CACHE_CHECK([for inttypes.h], [gl_cv_header_inttypes_h], + [AC_TRY_COMPILE( + [#include +#include ], + [uintmax_t i = (uintmax_t) -1; return !i;], + [gl_cv_header_inttypes_h=yes], + [gl_cv_header_inttypes_h=no])]) + if test $gl_cv_header_inttypes_h = yes; then + AC_DEFINE_UNQUOTED([HAVE_INTTYPES_H_WITH_UINTMAX], [1], + [Define if exists, doesn't clash with , + and declares uintmax_t. ]) + fi +]) diff --git a/m4/ld-version-script.m4 b/m4/ld-version-script.m4 new file mode 100644 index 000000000..a97888f24 --- /dev/null +++ b/m4/ld-version-script.m4 @@ -0,0 +1,44 @@ +# ld-version-script.m4 serial 1 +dnl Copyright (C) 2008, 2009 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Simon Josefsson + +# FIXME: The test below returns a false positive for mingw +# cross-compiles, 'local:' statements does not reduce number of +# exported symbols in a DLL. Use --disable-ld-version-script to work +# around the problem. + +# gl_LD_VERSION_SCRIPT +# -------------------- +# Check if LD supports linker scripts, and define automake conditional +# HAVE_LD_VERSION_SCRIPT if so. +AC_DEFUN([gl_LD_VERSION_SCRIPT], +[ + AC_ARG_ENABLE([ld-version-script], + AS_HELP_STRING([--enable-ld-version-script], + [enable linker version script (default is enabled when possible)]), + [have_ld_version_script=$enableval], []) + if test -z "$have_ld_version_script"; then + AC_MSG_CHECKING([if LD -Wl,--version-script works]) + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -Wl,--version-script=conftest.map" + cat > conftest.map <&1 conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by GCC]) + 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. + [[\\/]* | [A-Za-z]:[\\/]*)] + [re_direlt='/[^/][^/]*/\.\./'] + # Canonicalize the path 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 + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL([acl_cv_path_LD], +[if test -z "$LD"; then + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + acl_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some GNU ld's only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$acl_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="$ac_save_ifs" +else + acl_cv_path_LD="$LD" # Let the user override the test with a path. +fi]) +LD="$acl_cv_path_LD" +if test -n "$LD"; then + AC_MSG_RESULT([$LD]) +else + AC_MSG_RESULT([no]) +fi +test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) +AC_LIB_PROG_LD_GNU +]) diff --git a/m4/lib-link.m4 b/m4/lib-link.m4 new file mode 100644 index 000000000..2f8b7ff38 --- /dev/null +++ b/m4/lib-link.m4 @@ -0,0 +1,764 @@ +# lib-link.m4 serial 20 (gettext-0.18) +dnl Copyright (C) 2001-2009 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. + +AC_PREREQ([2.54]) + +dnl AC_LIB_LINKFLAGS(name [, dependencies]) searches for libname and +dnl the libraries corresponding to explicit and implicit dependencies. +dnl Sets and AC_SUBSTs the LIB${NAME} and LTLIB${NAME} variables and +dnl augments the CPPFLAGS variable. +dnl Sets and AC_SUBSTs the LIB${NAME}_PREFIX variable to nonempty if libname +dnl was found in ${LIB${NAME}_PREFIX}/$acl_libdirstem. +AC_DEFUN([AC_LIB_LINKFLAGS], +[ + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + AC_REQUIRE([AC_LIB_RPATH]) + pushdef([Name],[translit([$1],[./-], [___])]) + pushdef([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) + AC_CACHE_CHECK([how to link with lib[]$1], [ac_cv_lib[]Name[]_libs], [ + AC_LIB_LINKFLAGS_BODY([$1], [$2]) + ac_cv_lib[]Name[]_libs="$LIB[]NAME" + ac_cv_lib[]Name[]_ltlibs="$LTLIB[]NAME" + ac_cv_lib[]Name[]_cppflags="$INC[]NAME" + ac_cv_lib[]Name[]_prefix="$LIB[]NAME[]_PREFIX" + ]) + LIB[]NAME="$ac_cv_lib[]Name[]_libs" + LTLIB[]NAME="$ac_cv_lib[]Name[]_ltlibs" + INC[]NAME="$ac_cv_lib[]Name[]_cppflags" + LIB[]NAME[]_PREFIX="$ac_cv_lib[]Name[]_prefix" + AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME) + AC_SUBST([LIB]NAME) + AC_SUBST([LTLIB]NAME) + AC_SUBST([LIB]NAME[_PREFIX]) + dnl Also set HAVE_LIB[]NAME so that AC_LIB_HAVE_LINKFLAGS can reuse the + dnl results of this search when this library appears as a dependency. + HAVE_LIB[]NAME=yes + popdef([NAME]) + popdef([Name]) +]) + +dnl AC_LIB_HAVE_LINKFLAGS(name, dependencies, includes, testcode, [missing-message]) +dnl searches for libname and the libraries corresponding to explicit and +dnl implicit dependencies, together with the specified include files and +dnl the ability to compile and link the specified testcode. The missing-message +dnl defaults to 'no' and may contain additional hints for the user. +dnl If found, it sets and AC_SUBSTs HAVE_LIB${NAME}=yes and the LIB${NAME} +dnl and LTLIB${NAME} variables and augments the CPPFLAGS variable, and +dnl #defines HAVE_LIB${NAME} to 1. Otherwise, it sets and AC_SUBSTs +dnl HAVE_LIB${NAME}=no and LIB${NAME} and LTLIB${NAME} to empty. +dnl Sets and AC_SUBSTs the LIB${NAME}_PREFIX variable to nonempty if libname +dnl was found in ${LIB${NAME}_PREFIX}/$acl_libdirstem. +AC_DEFUN([AC_LIB_HAVE_LINKFLAGS], +[ + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + AC_REQUIRE([AC_LIB_RPATH]) + pushdef([Name],[translit([$1],[./-], [___])]) + pushdef([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) + + dnl Search for lib[]Name and define LIB[]NAME, LTLIB[]NAME and INC[]NAME + dnl accordingly. + AC_LIB_LINKFLAGS_BODY([$1], [$2]) + + dnl Add $INC[]NAME to CPPFLAGS before performing the following checks, + dnl because if the user has installed lib[]Name and not disabled its use + dnl via --without-lib[]Name-prefix, he wants to use it. + ac_save_CPPFLAGS="$CPPFLAGS" + AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME) + + AC_CACHE_CHECK([for lib[]$1], [ac_cv_lib[]Name], [ + ac_save_LIBS="$LIBS" + LIBS="$LIBS $LIB[]NAME" + AC_TRY_LINK([$3], [$4], + [ac_cv_lib[]Name=yes], + [ac_cv_lib[]Name='m4_if([$5], [], [no], [[$5]])']) + LIBS="$ac_save_LIBS" + ]) + if test "$ac_cv_lib[]Name" = yes; then + HAVE_LIB[]NAME=yes + AC_DEFINE([HAVE_LIB]NAME, 1, [Define if you have the lib][$1 library.]) + AC_MSG_CHECKING([how to link with lib[]$1]) + AC_MSG_RESULT([$LIB[]NAME]) + else + HAVE_LIB[]NAME=no + dnl If $LIB[]NAME didn't lead to a usable library, we don't need + dnl $INC[]NAME either. + CPPFLAGS="$ac_save_CPPFLAGS" + LIB[]NAME= + LTLIB[]NAME= + LIB[]NAME[]_PREFIX= + fi + AC_SUBST([HAVE_LIB]NAME) + AC_SUBST([LIB]NAME) + AC_SUBST([LTLIB]NAME) + AC_SUBST([LIB]NAME[_PREFIX]) + popdef([NAME]) + popdef([Name]) +]) + +dnl Determine the platform dependent parameters needed to use rpath: +dnl acl_libext, +dnl acl_shlibext, +dnl acl_hardcode_libdir_flag_spec, +dnl acl_hardcode_libdir_separator, +dnl acl_hardcode_direct, +dnl acl_hardcode_minus_L. +AC_DEFUN([AC_LIB_RPATH], +[ + dnl Tell automake >= 1.10 to complain if config.rpath is missing. + m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([config.rpath])]) + AC_REQUIRE([AC_PROG_CC]) dnl we use $CC, $GCC, $LDFLAGS + AC_REQUIRE([AC_LIB_PROG_LD]) dnl we use $LD, $with_gnu_ld + AC_REQUIRE([AC_CANONICAL_HOST]) dnl we use $host + AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT]) dnl we use $ac_aux_dir + AC_CACHE_CHECK([for shared library run path origin], [acl_cv_rpath], [ + CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \ + ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh + . ./conftest.sh + rm -f ./conftest.sh + acl_cv_rpath=done + ]) + wl="$acl_cv_wl" + acl_libext="$acl_cv_libext" + acl_shlibext="$acl_cv_shlibext" + acl_libname_spec="$acl_cv_libname_spec" + acl_library_names_spec="$acl_cv_library_names_spec" + acl_hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec" + acl_hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator" + acl_hardcode_direct="$acl_cv_hardcode_direct" + acl_hardcode_minus_L="$acl_cv_hardcode_minus_L" + dnl Determine whether the user wants rpath handling at all. + AC_ARG_ENABLE([rpath], + [ --disable-rpath do not hardcode runtime library paths], + :, enable_rpath=yes) +]) + +dnl AC_LIB_FROMPACKAGE(name, package) +dnl declares that libname comes from the given package. The configure file +dnl will then not have a --with-libname-prefix option but a +dnl --with-package-prefix option. Several libraries can come from the same +dnl package. This declaration must occur before an AC_LIB_LINKFLAGS or similar +dnl macro call that searches for libname. +AC_DEFUN([AC_LIB_FROMPACKAGE], +[ + pushdef([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) + define([acl_frompackage_]NAME, [$2]) + popdef([NAME]) + pushdef([PACK],[$2]) + pushdef([PACKUP],[translit(PACK,[abcdefghijklmnopqrstuvwxyz./-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) + define([acl_libsinpackage_]PACKUP, + m4_ifdef([acl_libsinpackage_]PACKUP, [acl_libsinpackage_]PACKUP[[, ]],)[lib$1]) + popdef([PACKUP]) + popdef([PACK]) +]) + +dnl AC_LIB_LINKFLAGS_BODY(name [, dependencies]) searches for libname and +dnl the libraries corresponding to explicit and implicit dependencies. +dnl Sets the LIB${NAME}, LTLIB${NAME} and INC${NAME} variables. +dnl Also, sets the LIB${NAME}_PREFIX variable to nonempty if libname was found +dnl in ${LIB${NAME}_PREFIX}/$acl_libdirstem. +AC_DEFUN([AC_LIB_LINKFLAGS_BODY], +[ + AC_REQUIRE([AC_LIB_PREPARE_MULTILIB]) + pushdef([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) + pushdef([PACK],[m4_ifdef([acl_frompackage_]NAME, [acl_frompackage_]NAME, lib[$1])]) + pushdef([PACKUP],[translit(PACK,[abcdefghijklmnopqrstuvwxyz./-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) + pushdef([PACKLIBS],[m4_ifdef([acl_frompackage_]NAME, [acl_libsinpackage_]PACKUP, lib[$1])]) + dnl Autoconf >= 2.61 supports dots in --with options. + pushdef([P_A_C_K],[m4_if(m4_version_compare(m4_defn([m4_PACKAGE_VERSION]),[2.61]),[-1],[translit(PACK,[.],[_])],PACK)]) + dnl By default, look in $includedir and $libdir. + use_additional=yes + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + AC_ARG_WITH(P_A_C_K[-prefix], +[[ --with-]]P_A_C_K[[-prefix[=DIR] search for ]PACKLIBS[ in DIR/include and DIR/lib + --without-]]P_A_C_K[[-prefix don't search for ]PACKLIBS[ in includedir and libdir]], +[ + if test "X$withval" = "Xno"; then + use_additional=no + else + if test "X$withval" = "X"; then + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + else + additional_includedir="$withval/include" + additional_libdir="$withval/$acl_libdirstem" + if test "$acl_libdirstem2" != "$acl_libdirstem" \ + && ! test -d "$withval/$acl_libdirstem"; then + additional_libdir="$withval/$acl_libdirstem2" + fi + fi + fi +]) + dnl Search the library and its dependencies in $additional_libdir and + dnl $LDFLAGS. Using breadth-first-seach. + LIB[]NAME= + LTLIB[]NAME= + INC[]NAME= + LIB[]NAME[]_PREFIX= + dnl HAVE_LIB${NAME} is an indicator that LIB${NAME}, LTLIB${NAME} have been + dnl computed. So it has to be reset here. + HAVE_LIB[]NAME= + rpathdirs= + ltrpathdirs= + names_already_handled= + names_next_round='$1 $2' + while test -n "$names_next_round"; do + names_this_round="$names_next_round" + names_next_round= + for name in $names_this_round; do + already_handled= + for n in $names_already_handled; do + if test "$n" = "$name"; then + already_handled=yes + break + fi + done + if test -z "$already_handled"; then + names_already_handled="$names_already_handled $name" + dnl See if it was already located by an earlier AC_LIB_LINKFLAGS + dnl or AC_LIB_HAVE_LINKFLAGS call. + uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'` + eval value=\"\$HAVE_LIB$uppername\" + if test -n "$value"; then + if test "$value" = yes; then + eval value=\"\$LIB$uppername\" + test -z "$value" || LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$value" + eval value=\"\$LTLIB$uppername\" + test -z "$value" || LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$value" + else + dnl An earlier call to AC_LIB_HAVE_LINKFLAGS has determined + dnl that this library doesn't exist. So just drop it. + : + fi + else + dnl Search the library lib$name in $additional_libdir and $LDFLAGS + dnl and the already constructed $LIBNAME/$LTLIBNAME. + found_dir= + found_la= + found_so= + found_a= + eval libname=\"$acl_libname_spec\" # typically: libname=lib$name + if test -n "$acl_shlibext"; then + shrext=".$acl_shlibext" # typically: shrext=.so + else + shrext= + fi + if test $use_additional = yes; then + dir="$additional_libdir" + dnl The same code as in the loop below: + dnl First look for a shared library. + if test -n "$acl_shlibext"; then + if test -f "$dir/$libname$shrext"; then + found_dir="$dir" + found_so="$dir/$libname$shrext" + else + if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then + ver=`(cd "$dir" && \ + for f in "$libname$shrext".*; do echo "$f"; done \ + | sed -e "s,^$libname$shrext\\\\.,," \ + | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ + | sed 1q ) 2>/dev/null` + if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then + found_dir="$dir" + found_so="$dir/$libname$shrext.$ver" + fi + else + eval library_names=\"$acl_library_names_spec\" + for f in $library_names; do + if test -f "$dir/$f"; then + found_dir="$dir" + found_so="$dir/$f" + break + fi + done + fi + fi + fi + dnl Then look for a static library. + if test "X$found_dir" = "X"; then + if test -f "$dir/$libname.$acl_libext"; then + found_dir="$dir" + found_a="$dir/$libname.$acl_libext" + fi + fi + if test "X$found_dir" != "X"; then + if test -f "$dir/$libname.la"; then + found_la="$dir/$libname.la" + fi + fi + fi + if test "X$found_dir" = "X"; then + for x in $LDFLAGS $LTLIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + case "$x" in + -L*) + dir=`echo "X$x" | sed -e 's/^X-L//'` + dnl First look for a shared library. + if test -n "$acl_shlibext"; then + if test -f "$dir/$libname$shrext"; then + found_dir="$dir" + found_so="$dir/$libname$shrext" + else + if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then + ver=`(cd "$dir" && \ + for f in "$libname$shrext".*; do echo "$f"; done \ + | sed -e "s,^$libname$shrext\\\\.,," \ + | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ + | sed 1q ) 2>/dev/null` + if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then + found_dir="$dir" + found_so="$dir/$libname$shrext.$ver" + fi + else + eval library_names=\"$acl_library_names_spec\" + for f in $library_names; do + if test -f "$dir/$f"; then + found_dir="$dir" + found_so="$dir/$f" + break + fi + done + fi + fi + fi + dnl Then look for a static library. + if test "X$found_dir" = "X"; then + if test -f "$dir/$libname.$acl_libext"; then + found_dir="$dir" + found_a="$dir/$libname.$acl_libext" + fi + fi + if test "X$found_dir" != "X"; then + if test -f "$dir/$libname.la"; then + found_la="$dir/$libname.la" + fi + fi + ;; + esac + if test "X$found_dir" != "X"; then + break + fi + done + fi + if test "X$found_dir" != "X"; then + dnl Found the library. + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$found_dir -l$name" + if test "X$found_so" != "X"; then + dnl Linking with a shared library. We attempt to hardcode its + dnl directory into the executable's runpath, unless it's the + dnl standard /usr/lib. + if test "$enable_rpath" = no \ + || test "X$found_dir" = "X/usr/$acl_libdirstem" \ + || test "X$found_dir" = "X/usr/$acl_libdirstem2"; then + dnl No hardcoding is needed. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + else + dnl Use an explicit option to hardcode DIR into the resulting + dnl binary. + dnl Potentially add DIR to ltrpathdirs. + dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $found_dir" + fi + dnl The hardcoding into $LIBNAME is system dependent. + if test "$acl_hardcode_direct" = yes; then + dnl Using DIR/libNAME.so during linking hardcodes DIR into the + dnl resulting binary. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + else + if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then + dnl Use an explicit option to hardcode DIR into the resulting + dnl binary. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + dnl Potentially add DIR to rpathdirs. + dnl The rpathdirs will be appended to $LIBNAME at the end. + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $found_dir" + fi + else + dnl Rely on "-L$found_dir". + dnl But don't add it if it's already contained in the LDFLAGS + dnl or the already constructed $LIBNAME + haveit= + for x in $LDFLAGS $LIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir" + fi + if test "$acl_hardcode_minus_L" != no; then + dnl FIXME: Not sure whether we should use + dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" + dnl here. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + else + dnl We cannot use $acl_hardcode_runpath_var and LD_RUN_PATH + dnl here, because this doesn't fit in flags passed to the + dnl compiler. So give up. No hardcoding. This affects only + dnl very old systems. + dnl FIXME: Not sure whether we should use + dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" + dnl here. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" + fi + fi + fi + fi + else + if test "X$found_a" != "X"; then + dnl Linking with a static library. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_a" + else + dnl We shouldn't come here, but anyway it's good to have a + dnl fallback. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir -l$name" + fi + fi + dnl Assume the include files are nearby. + additional_includedir= + case "$found_dir" in + */$acl_libdirstem | */$acl_libdirstem/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'` + if test "$name" = '$1'; then + LIB[]NAME[]_PREFIX="$basedir" + fi + additional_includedir="$basedir/include" + ;; + */$acl_libdirstem2 | */$acl_libdirstem2/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem2/"'*$,,'` + if test "$name" = '$1'; then + LIB[]NAME[]_PREFIX="$basedir" + fi + additional_includedir="$basedir/include" + ;; + esac + if test "X$additional_includedir" != "X"; then + dnl Potentially add $additional_includedir to $INCNAME. + dnl But don't add it + dnl 1. if it's the standard /usr/include, + dnl 2. if it's /usr/local/include and we are using GCC on Linux, + dnl 3. if it's already present in $CPPFLAGS or the already + dnl constructed $INCNAME, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_includedir" != "X/usr/include"; then + haveit= + if test "X$additional_includedir" = "X/usr/local/include"; then + if test -n "$GCC"; then + case $host_os in + linux* | gnu* | k*bsd*-gnu) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + for x in $CPPFLAGS $INC[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-I$additional_includedir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_includedir"; then + dnl Really add $additional_includedir to $INCNAME. + INC[]NAME="${INC[]NAME}${INC[]NAME:+ }-I$additional_includedir" + fi + fi + fi + fi + fi + dnl Look for dependencies. + if test -n "$found_la"; then + dnl Read the .la file. It defines the variables + dnl dlname, library_names, old_library, dependency_libs, current, + dnl age, revision, installed, dlopen, dlpreopen, libdir. + save_libdir="$libdir" + case "$found_la" in + */* | *\\*) . "$found_la" ;; + *) . "./$found_la" ;; + esac + libdir="$save_libdir" + dnl We use only dependency_libs. + for dep in $dependency_libs; do + case "$dep" in + -L*) + additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` + dnl Potentially add $additional_libdir to $LIBNAME and $LTLIBNAME. + dnl But don't add it + dnl 1. if it's the standard /usr/lib, + dnl 2. if it's /usr/local/lib and we are using GCC on Linux, + dnl 3. if it's already present in $LDFLAGS or the already + dnl constructed $LIBNAME, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_libdir" != "X/usr/$acl_libdirstem" \ + && test "X$additional_libdir" != "X/usr/$acl_libdirstem2"; then + haveit= + if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem" \ + || test "X$additional_libdir" = "X/usr/local/$acl_libdirstem2"; then + if test -n "$GCC"; then + case $host_os in + linux* | gnu* | k*bsd*-gnu) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + haveit= + for x in $LDFLAGS $LIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + dnl Really add $additional_libdir to $LIBNAME. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$additional_libdir" + fi + fi + haveit= + for x in $LDFLAGS $LTLIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + dnl Really add $additional_libdir to $LTLIBNAME. + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$additional_libdir" + fi + fi + fi + fi + ;; + -R*) + dir=`echo "X$dep" | sed -e 's/^X-R//'` + if test "$enable_rpath" != no; then + dnl Potentially add DIR to rpathdirs. + dnl The rpathdirs will be appended to $LIBNAME at the end. + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $dir" + fi + dnl Potentially add DIR to ltrpathdirs. + dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $dir" + fi + fi + ;; + -l*) + dnl Handle this in the next round. + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` + ;; + *.la) + dnl Handle this in the next round. Throw away the .la's + dnl directory; it is already contained in a preceding -L + dnl option. + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` + ;; + *) + dnl Most likely an immediate library name. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$dep" + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$dep" + ;; + esac + done + fi + else + dnl Didn't find the library; assume it is in the system directories + dnl known to the linker and runtime loader. (All the system + dnl directories known to the linker should also be known to the + dnl runtime loader, otherwise the system is severely misconfigured.) + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-l$name" + fi + fi + fi + done + done + if test "X$rpathdirs" != "X"; then + if test -n "$acl_hardcode_libdir_separator"; then + dnl Weird platform: only the last -rpath option counts, the user must + dnl pass all path elements in one option. We can arrange that for a + dnl single library, but not when more than one $LIBNAMEs are used. + alldirs= + for found_dir in $rpathdirs; do + alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir" + done + dnl Note: acl_hardcode_libdir_flag_spec uses $libdir and $wl. + acl_save_libdir="$libdir" + libdir="$alldirs" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" + else + dnl The -rpath options are cumulative. + for found_dir in $rpathdirs; do + acl_save_libdir="$libdir" + libdir="$found_dir" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" + done + fi + fi + if test "X$ltrpathdirs" != "X"; then + dnl When using libtool, the option that works for both libraries and + dnl executables is -R. The -R options are cumulative. + for found_dir in $ltrpathdirs; do + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-R$found_dir" + done + fi + popdef([P_A_C_K]) + popdef([PACKLIBS]) + popdef([PACKUP]) + popdef([PACK]) + popdef([NAME]) +]) + +dnl AC_LIB_APPENDTOVAR(VAR, CONTENTS) appends the elements of CONTENTS to VAR, +dnl unless already present in VAR. +dnl Works only for CPPFLAGS, not for LIB* variables because that sometimes +dnl contains two or three consecutive elements that belong together. +AC_DEFUN([AC_LIB_APPENDTOVAR], +[ + for element in [$2]; do + haveit= + for x in $[$1]; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X$element"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + [$1]="${[$1]}${[$1]:+ }$element" + fi + done +]) + +dnl For those cases where a variable contains several -L and -l options +dnl referring to unknown libraries and directories, this macro determines the +dnl necessary additional linker options for the runtime path. +dnl AC_LIB_LINKFLAGS_FROM_LIBS([LDADDVAR], [LIBSVALUE], [USE-LIBTOOL]) +dnl sets LDADDVAR to linker options needed together with LIBSVALUE. +dnl If USE-LIBTOOL evaluates to non-empty, linking with libtool is assumed, +dnl otherwise linking without libtool is assumed. +AC_DEFUN([AC_LIB_LINKFLAGS_FROM_LIBS], +[ + AC_REQUIRE([AC_LIB_RPATH]) + AC_REQUIRE([AC_LIB_PREPARE_MULTILIB]) + $1= + if test "$enable_rpath" != no; then + if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then + dnl Use an explicit option to hardcode directories into the resulting + dnl binary. + rpathdirs= + next= + for opt in $2; do + if test -n "$next"; then + dir="$next" + dnl No need to hardcode the standard /usr/lib. + if test "X$dir" != "X/usr/$acl_libdirstem" \ + && test "X$dir" != "X/usr/$acl_libdirstem2"; then + rpathdirs="$rpathdirs $dir" + fi + next= + else + case $opt in + -L) next=yes ;; + -L*) dir=`echo "X$opt" | sed -e 's,^X-L,,'` + dnl No need to hardcode the standard /usr/lib. + if test "X$dir" != "X/usr/$acl_libdirstem" \ + && test "X$dir" != "X/usr/$acl_libdirstem2"; then + rpathdirs="$rpathdirs $dir" + fi + next= ;; + *) next= ;; + esac + fi + done + if test "X$rpathdirs" != "X"; then + if test -n ""$3""; then + dnl libtool is used for linking. Use -R options. + for dir in $rpathdirs; do + $1="${$1}${$1:+ }-R$dir" + done + else + dnl The linker is used for linking directly. + if test -n "$acl_hardcode_libdir_separator"; then + dnl Weird platform: only the last -rpath option counts, the user + dnl must pass all path elements in one option. + alldirs= + for dir in $rpathdirs; do + alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$dir" + done + acl_save_libdir="$libdir" + libdir="$alldirs" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + $1="$flag" + else + dnl The -rpath options are cumulative. + for dir in $rpathdirs; do + acl_save_libdir="$libdir" + libdir="$dir" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + $1="${$1}${$1:+ }$flag" + done + fi + fi + fi + fi + fi + AC_SUBST([$1]) +]) diff --git a/m4/lib-prefix.m4 b/m4/lib-prefix.m4 new file mode 100644 index 000000000..4b7ee3358 --- /dev/null +++ b/m4/lib-prefix.m4 @@ -0,0 +1,224 @@ +# lib-prefix.m4 serial 7 (gettext-0.18) +dnl Copyright (C) 2001-2005, 2008-2009 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. + +dnl AC_LIB_ARG_WITH is synonymous to AC_ARG_WITH in autoconf-2.13, and +dnl similar to AC_ARG_WITH in autoconf 2.52...2.57 except that is doesn't +dnl require excessive bracketing. +ifdef([AC_HELP_STRING], +[AC_DEFUN([AC_LIB_ARG_WITH], [AC_ARG_WITH([$1],[[$2]],[$3],[$4])])], +[AC_DEFUN([AC_][LIB_ARG_WITH], [AC_ARG_WITH([$1],[$2],[$3],[$4])])]) + +dnl AC_LIB_PREFIX adds to the CPPFLAGS and LDFLAGS the flags that are needed +dnl to access previously installed libraries. The basic assumption is that +dnl a user will want packages to use other packages he previously installed +dnl with the same --prefix option. +dnl This macro is not needed if only AC_LIB_LINKFLAGS is used to locate +dnl libraries, but is otherwise very convenient. +AC_DEFUN([AC_LIB_PREFIX], +[ + AC_BEFORE([$0], [AC_LIB_LINKFLAGS]) + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_REQUIRE([AC_LIB_PREPARE_MULTILIB]) + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + dnl By default, look in $includedir and $libdir. + use_additional=yes + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + AC_LIB_ARG_WITH([lib-prefix], +[ --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib + --without-lib-prefix don't search for libraries in includedir and libdir], +[ + if test "X$withval" = "Xno"; then + use_additional=no + else + if test "X$withval" = "X"; then + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + else + additional_includedir="$withval/include" + additional_libdir="$withval/$acl_libdirstem" + fi + fi +]) + if test $use_additional = yes; then + dnl Potentially add $additional_includedir to $CPPFLAGS. + dnl But don't add it + dnl 1. if it's the standard /usr/include, + dnl 2. if it's already present in $CPPFLAGS, + dnl 3. if it's /usr/local/include and we are using GCC on Linux, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_includedir" != "X/usr/include"; then + haveit= + for x in $CPPFLAGS; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-I$additional_includedir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test "X$additional_includedir" = "X/usr/local/include"; then + if test -n "$GCC"; then + case $host_os in + linux* | gnu* | k*bsd*-gnu) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + if test -d "$additional_includedir"; then + dnl Really add $additional_includedir to $CPPFLAGS. + CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }-I$additional_includedir" + fi + fi + fi + fi + dnl Potentially add $additional_libdir to $LDFLAGS. + dnl But don't add it + dnl 1. if it's the standard /usr/lib, + dnl 2. if it's already present in $LDFLAGS, + dnl 3. if it's /usr/local/lib and we are using GCC on Linux, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_libdir" != "X/usr/$acl_libdirstem"; then + haveit= + for x in $LDFLAGS; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem"; then + if test -n "$GCC"; then + case $host_os in + linux*) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + dnl Really add $additional_libdir to $LDFLAGS. + LDFLAGS="${LDFLAGS}${LDFLAGS:+ }-L$additional_libdir" + fi + fi + fi + fi + fi +]) + +dnl AC_LIB_PREPARE_PREFIX creates variables acl_final_prefix, +dnl acl_final_exec_prefix, containing the values to which $prefix and +dnl $exec_prefix will expand at the end of the configure script. +AC_DEFUN([AC_LIB_PREPARE_PREFIX], +[ + dnl Unfortunately, prefix and exec_prefix get only finally determined + dnl at the end of configure. + if test "X$prefix" = "XNONE"; then + acl_final_prefix="$ac_default_prefix" + else + acl_final_prefix="$prefix" + fi + if test "X$exec_prefix" = "XNONE"; then + acl_final_exec_prefix='${prefix}' + else + acl_final_exec_prefix="$exec_prefix" + fi + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + eval acl_final_exec_prefix=\"$acl_final_exec_prefix\" + prefix="$acl_save_prefix" +]) + +dnl AC_LIB_WITH_FINAL_PREFIX([statement]) evaluates statement, with the +dnl variables prefix and exec_prefix bound to the values they will have +dnl at the end of the configure script. +AC_DEFUN([AC_LIB_WITH_FINAL_PREFIX], +[ + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + $1 + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" +]) + +dnl AC_LIB_PREPARE_MULTILIB creates +dnl - a variable acl_libdirstem, containing the basename of the libdir, either +dnl "lib" or "lib64" or "lib/64", +dnl - a variable acl_libdirstem2, as a secondary possible value for +dnl acl_libdirstem, either the same as acl_libdirstem or "lib/sparcv9" or +dnl "lib/amd64". +AC_DEFUN([AC_LIB_PREPARE_MULTILIB], +[ + dnl There is no formal standard regarding lib and lib64. + dnl On glibc systems, the current practice is that on a system supporting + dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under + dnl $prefix/lib64 and 32-bit libraries go under $prefix/lib. We determine + dnl the compiler's default mode by looking at the compiler's library search + dnl path. If at least one of its elements ends in /lib64 or points to a + dnl directory whose absolute pathname ends in /lib64, we assume a 64-bit ABI. + dnl Otherwise we use the default, namely "lib". + dnl On Solaris systems, the current practice is that on a system supporting + dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under + dnl $prefix/lib/64 (which is a symlink to either $prefix/lib/sparcv9 or + dnl $prefix/lib/amd64) and 32-bit libraries go under $prefix/lib. + AC_REQUIRE([AC_CANONICAL_HOST]) + acl_libdirstem=lib + acl_libdirstem2= + case "$host_os" in + solaris*) + dnl See Solaris 10 Software Developer Collection > Solaris 64-bit Developer's Guide > The Development Environment + dnl . + dnl "Portable Makefiles should refer to any library directories using the 64 symbolic link." + dnl But we want to recognize the sparcv9 or amd64 subdirectory also if the + dnl symlink is missing, so we set acl_libdirstem2 too. + AC_CACHE_CHECK([for 64-bit host], [gl_cv_solaris_64bit], + [AC_EGREP_CPP([sixtyfour bits], [ +#ifdef _LP64 +sixtyfour bits +#endif + ], [gl_cv_solaris_64bit=yes], [gl_cv_solaris_64bit=no]) + ]) + if test $gl_cv_solaris_64bit = yes; then + acl_libdirstem=lib/64 + case "$host_cpu" in + sparc*) acl_libdirstem2=lib/sparcv9 ;; + i*86 | x86_64) acl_libdirstem2=lib/amd64 ;; + esac + fi + ;; + *) + searchpath=`(LC_ALL=C $CC -print-search-dirs) 2>/dev/null | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'` + if test -n "$searchpath"; then + acl_save_IFS="${IFS= }"; IFS=":" + for searchdir in $searchpath; do + if test -d "$searchdir"; then + case "$searchdir" in + */lib64/ | */lib64 ) acl_libdirstem=lib64 ;; + */../ | */.. ) + # Better ignore directories of this form. They are misleading. + ;; + *) searchdir=`cd "$searchdir" && pwd` + case "$searchdir" in + */lib64 ) acl_libdirstem=lib64 ;; + esac ;; + esac + fi + done + IFS="$acl_save_IFS" + fi + ;; + esac + test -n "$acl_libdirstem2" || acl_libdirstem2="$acl_libdirstem" +]) diff --git a/m4/libunistring.m4 b/m4/libunistring.m4 new file mode 100644 index 000000000..52ff06b61 --- /dev/null +++ b/m4/libunistring.m4 @@ -0,0 +1,37 @@ +# libunistring.m4 serial 1 +dnl Copyright (C) 2009 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl gl_LIBUNISTRING +dnl Searches for an installed libunistring. +dnl If found, it sets and AC_SUBSTs HAVE_LIBUNISTRING=yes and the LIBUNISTRING +dnl and LTLIBUNISTRING variables and augments the CPPFLAGS variable, and +dnl #defines HAVE_LIBUNISTRING to 1. Otherwise, it sets and AC_SUBSTs +dnl HAVE_LIBUNISTRING=no and LIBUNINSTRING and LTLIBUNISTRING to empty. + +AC_DEFUN([gl_LIBUNISTRING], +[ + dnl First, try to link without -liconv. libunistring often depends on + dnl libiconv, but we don't know (and often don't need to know) where + dnl libiconv is installed. + AC_LIB_HAVE_LINKFLAGS([unistring], [], + [#include ], [u8_strconv_from_locale((char*)0);], + [no, consider installing GNU libunistring]) + if test "$ac_cv_libunistring" != yes; then + dnl Second try, with -liconv. + AC_REQUIRE([AM_ICONV]) + if test -n "$LIBICONV"; then + glus_save_LIBS="$LIBS" + LIBS="$LIBS $LIBICONV" + AC_LIB_HAVE_LINKFLAGS([unistring], [], + [#include ], [u8_strconv_from_locale((char*)0);], + [no, consider installing GNU libunistring]) + if test -n "$LIBUNISTRING"; then + LIBUNISTRING="$LIBUNISTRING $LIBICONV" + fi + LIBS="$glus_save_LIBS" + fi + fi +]) diff --git a/m4/localcharset.m4 b/m4/localcharset.m4 index b2b77338e..e9601041c 100644 --- a/m4/localcharset.m4 +++ b/m4/localcharset.m4 @@ -1,5 +1,5 @@ -# localcharset.m4 serial 5 -dnl Copyright (C) 2002, 2004, 2006 Free Software Foundation, Inc. +# localcharset.m4 serial 6 +dnl Copyright (C) 2002, 2004, 2006, 2009 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. @@ -8,7 +8,7 @@ AC_DEFUN([gl_LOCALCHARSET], [ dnl Prerequisites of lib/localcharset.c. AC_REQUIRE([AM_LANGINFO_CODESET]) - AC_CHECK_DECLS_ONCE(getc_unlocked) + AC_CHECK_DECLS_ONCE([getc_unlocked]) dnl Prerequisites of the lib/Makefile.am snippet. AC_REQUIRE([AC_CANONICAL_HOST]) diff --git a/m4/locale-fr.m4 b/m4/locale-fr.m4 index ac8a78d2c..653a5bc2b 100644 --- a/m4/locale-fr.m4 +++ b/m4/locale-fr.m4 @@ -1,5 +1,5 @@ -# locale-fr.m4 serial 9 -dnl Copyright (C) 2003, 2005-2008 Free Software Foundation, Inc. +# locale-fr.m4 serial 11 +dnl Copyright (C) 2003, 2005-2009 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. @@ -11,26 +11,8 @@ AC_DEFUN([gt_LOCALE_FR], [ AC_REQUIRE([AC_CANONICAL_HOST]) AC_REQUIRE([AM_LANGINFO_CODESET]) - AC_CACHE_CHECK([for a traditional french locale], gt_cv_locale_fr, [ - macosx= -changequote(,)dnl - case "$host_os" in - darwin[56]*) ;; - darwin*) macosx=yes;; - esac -changequote([,])dnl - if test -n "$macosx"; then - # On Darwin 7 (MacOS X), the libc supports some locales in non-UTF-8 - # encodings, but the kernel does not support them. The documentation - # says: - # "... all code that calls BSD system routines should ensure - # that the const *char parameters of these routines are in UTF-8 - # encoding. All BSD system functions expect their string - # parameters to be in UTF-8 encoding and nothing else." - # See the comments in config.charset. Therefore we bypass the test. - gt_cv_locale_fr=none - else - AC_LANG_CONFTEST([AC_LANG_SOURCE([ + AC_CACHE_CHECK([for a traditional french locale], [gt_cv_locale_fr], [ + AC_LANG_CONFTEST([AC_LANG_SOURCE([ changequote(,)dnl #include #include @@ -75,42 +57,41 @@ int main () { return 0; } changequote([,])dnl - ])]) - if AC_TRY_EVAL([ac_link]) && test -s conftest$ac_exeext; then - # Setting LC_ALL is not enough. Need to set LC_TIME to empty, because - # otherwise on MacOS X 10.3.5 the LC_TIME=C from the beginning of the - # configure script would override the LC_ALL setting. Likewise for - # LC_CTYPE, which is also set at the beginning of the configure script. - # Test for the usual locale name. - if (LC_ALL=fr_FR LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then - gt_cv_locale_fr=fr_FR + ])]) + if AC_TRY_EVAL([ac_link]) && test -s conftest$ac_exeext; then + # Setting LC_ALL is not enough. Need to set LC_TIME to empty, because + # otherwise on MacOS X 10.3.5 the LC_TIME=C from the beginning of the + # configure script would override the LC_ALL setting. Likewise for + # LC_CTYPE, which is also set at the beginning of the configure script. + # Test for the usual locale name. + if (LC_ALL=fr_FR LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then + gt_cv_locale_fr=fr_FR + else + # Test for the locale name with explicit encoding suffix. + if (LC_ALL=fr_FR.ISO-8859-1 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then + gt_cv_locale_fr=fr_FR.ISO-8859-1 else - # Test for the locale name with explicit encoding suffix. - if (LC_ALL=fr_FR.ISO-8859-1 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then - gt_cv_locale_fr=fr_FR.ISO-8859-1 + # Test for the AIX, OSF/1, FreeBSD, NetBSD, OpenBSD locale name. + if (LC_ALL=fr_FR.ISO8859-1 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then + gt_cv_locale_fr=fr_FR.ISO8859-1 else - # Test for the AIX, OSF/1, FreeBSD, NetBSD, OpenBSD locale name. - if (LC_ALL=fr_FR.ISO8859-1 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then - gt_cv_locale_fr=fr_FR.ISO8859-1 + # Test for the HP-UX locale name. + if (LC_ALL=fr_FR.iso88591 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then + gt_cv_locale_fr=fr_FR.iso88591 else - # Test for the HP-UX locale name. - if (LC_ALL=fr_FR.iso88591 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then - gt_cv_locale_fr=fr_FR.iso88591 + # Test for the Solaris 7 locale name. + if (LC_ALL=fr LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then + gt_cv_locale_fr=fr else - # Test for the Solaris 7 locale name. - if (LC_ALL=fr LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then - gt_cv_locale_fr=fr - else - # None found. - gt_cv_locale_fr=none - fi + # None found. + gt_cv_locale_fr=none fi fi fi fi fi - rm -fr conftest* fi + rm -fr conftest* ]) LOCALE_FR=$gt_cv_locale_fr AC_SUBST([LOCALE_FR]) @@ -120,7 +101,7 @@ dnl Determine the name of a french locale with UTF-8 encoding. AC_DEFUN([gt_LOCALE_FR_UTF8], [ AC_REQUIRE([AM_LANGINFO_CODESET]) - AC_CACHE_CHECK([for a french Unicode locale], gt_cv_locale_fr_utf8, [ + AC_CACHE_CHECK([for a french Unicode locale], [gt_cv_locale_fr_utf8], [ AC_LANG_CONFTEST([AC_LANG_SOURCE([ changequote(,)dnl #include diff --git a/m4/locale-ja.m4 b/m4/locale-ja.m4 index c42064f72..936057647 100644 --- a/m4/locale-ja.m4 +++ b/m4/locale-ja.m4 @@ -1,5 +1,5 @@ -# locale-ja.m4 serial 5 -dnl Copyright (C) 2003, 2005-2008 Free Software Foundation, Inc. +# locale-ja.m4 serial 7 +dnl Copyright (C) 2003, 2005-2009 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. @@ -11,26 +11,8 @@ AC_DEFUN([gt_LOCALE_JA], [ AC_REQUIRE([AC_CANONICAL_HOST]) AC_REQUIRE([AM_LANGINFO_CODESET]) - AC_CACHE_CHECK([for a traditional japanese locale], gt_cv_locale_ja, [ - macosx= -changequote(,)dnl - case "$host_os" in - darwin[56]*) ;; - darwin*) macosx=yes;; - esac -changequote([,])dnl - if test -n "$macosx"; then - # On Darwin 7 (MacOS X), the libc supports some locales in non-UTF-8 - # encodings, but the kernel does not support them. The documentation - # says: - # "... all code that calls BSD system routines should ensure - # that the const *char parameters of these routines are in UTF-8 - # encoding. All BSD system functions expect their string - # parameters to be in UTF-8 encoding and nothing else." - # See the comments in config.charset. Therefore we bypass the test. - gt_cv_locale_ja=none - else - AC_LANG_CONFTEST([AC_LANG_SOURCE([ + AC_CACHE_CHECK([for a traditional japanese locale], [gt_cv_locale_ja], [ + AC_LANG_CONFTEST([AC_LANG_SOURCE([ changequote(,)dnl #include #include @@ -79,47 +61,46 @@ int main () return 0; } changequote([,])dnl - ])]) - if AC_TRY_EVAL([ac_link]) && test -s conftest$ac_exeext; then - # Setting LC_ALL is not enough. Need to set LC_TIME to empty, because - # otherwise on MacOS X 10.3.5 the LC_TIME=C from the beginning of the - # configure script would override the LC_ALL setting. Likewise for - # LC_CTYPE, which is also set at the beginning of the configure script. - # Test for the AIX locale name. - if (LC_ALL=ja_JP LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then - gt_cv_locale_ja=ja_JP + ])]) + if AC_TRY_EVAL([ac_link]) && test -s conftest$ac_exeext; then + # Setting LC_ALL is not enough. Need to set LC_TIME to empty, because + # otherwise on MacOS X 10.3.5 the LC_TIME=C from the beginning of the + # configure script would override the LC_ALL setting. Likewise for + # LC_CTYPE, which is also set at the beginning of the configure script. + # Test for the AIX locale name. + if (LC_ALL=ja_JP LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then + gt_cv_locale_ja=ja_JP + else + # Test for the locale name with explicit encoding suffix. + if (LC_ALL=ja_JP.EUC-JP LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then + gt_cv_locale_ja=ja_JP.EUC-JP else - # Test for the locale name with explicit encoding suffix. - if (LC_ALL=ja_JP.EUC-JP LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then - gt_cv_locale_ja=ja_JP.EUC-JP + # Test for the HP-UX, OSF/1, NetBSD locale name. + if (LC_ALL=ja_JP.eucJP LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then + gt_cv_locale_ja=ja_JP.eucJP else - # Test for the HP-UX, OSF/1, NetBSD locale name. - if (LC_ALL=ja_JP.eucJP LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then - gt_cv_locale_ja=ja_JP.eucJP + # Test for the IRIX, FreeBSD locale name. + if (LC_ALL=ja_JP.EUC LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then + gt_cv_locale_ja=ja_JP.EUC else - # Test for the IRIX, FreeBSD locale name. - if (LC_ALL=ja_JP.EUC LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then - gt_cv_locale_ja=ja_JP.EUC + # Test for the Solaris 7 locale name. + if (LC_ALL=ja LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then + gt_cv_locale_ja=ja else - # Test for the Solaris 7 locale name. - if (LC_ALL=ja LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then - gt_cv_locale_ja=ja + # Special test for NetBSD 1.6. + if test -f /usr/share/locale/ja_JP.eucJP/LC_CTYPE; then + gt_cv_locale_ja=ja_JP.eucJP else - # Special test for NetBSD 1.6. - if test -f /usr/share/locale/ja_JP.eucJP/LC_CTYPE; then - gt_cv_locale_ja=ja_JP.eucJP - else - # None found. - gt_cv_locale_ja=none - fi + # None found. + gt_cv_locale_ja=none fi fi fi fi fi fi - rm -fr conftest* fi + rm -fr conftest* ]) LOCALE_JA=$gt_cv_locale_ja AC_SUBST([LOCALE_JA]) diff --git a/m4/locale-zh.m4 b/m4/locale-zh.m4 index 594f62a69..36a5f1dfb 100644 --- a/m4/locale-zh.m4 +++ b/m4/locale-zh.m4 @@ -1,5 +1,5 @@ -# locale-zh.m4 serial 4 -dnl Copyright (C) 2003, 2005-2008 Free Software Foundation, Inc. +# locale-zh.m4 serial 6 +dnl Copyright (C) 2003, 2005-2009 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. @@ -11,26 +11,8 @@ AC_DEFUN([gt_LOCALE_ZH_CN], [ AC_REQUIRE([AC_CANONICAL_HOST]) AC_REQUIRE([AM_LANGINFO_CODESET]) - AC_CACHE_CHECK([for a transitional chinese locale], gt_cv_locale_zh_CN, [ - macosx= -changequote(,)dnl - case "$host_os" in - darwin[56]*) ;; - darwin*) macosx=yes;; - esac -changequote([,])dnl - if test -n "$macosx"; then - # On Darwin 7 (MacOS X), the libc supports some locales in non-UTF-8 - # encodings, but the kernel does not support them. The documentation - # says: - # "... all code that calls BSD system routines should ensure - # that the const *char parameters of these routines are in UTF-8 - # encoding. All BSD system functions expect their string - # parameters to be in UTF-8 encoding and nothing else." - # See the comments in config.charset. Therefore we bypass the test. - gt_cv_locale_zh_CN=none - else - AC_LANG_CONFTEST([AC_LANG_SOURCE([ + AC_CACHE_CHECK([for a transitional chinese locale], [gt_cv_locale_zh_CN], [ + AC_LANG_CONFTEST([AC_LANG_SOURCE([ changequote(,)dnl #include #include @@ -80,31 +62,30 @@ int main () return 0; } changequote([,])dnl - ])]) - if AC_TRY_EVAL([ac_link]) && test -s conftest$ac_exeext; then - # Setting LC_ALL is not enough. Need to set LC_TIME to empty, because - # otherwise on MacOS X 10.3.5 the LC_TIME=C from the beginning of the - # configure script would override the LC_ALL setting. Likewise for - # LC_CTYPE, which is also set at the beginning of the configure script. - # Test for the locale name without encoding suffix. - if (LC_ALL=zh_CN LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then - gt_cv_locale_zh_CN=zh_CN - else - # Test for the locale name with explicit encoding suffix. - if (LC_ALL=zh_CN.GB18030 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then - gt_cv_locale_zh_CN=zh_CN.GB18030 - else - # None found. - gt_cv_locale_zh_CN=none - fi - fi + ])]) + if AC_TRY_EVAL([ac_link]) && test -s conftest$ac_exeext; then + # Setting LC_ALL is not enough. Need to set LC_TIME to empty, because + # otherwise on MacOS X 10.3.5 the LC_TIME=C from the beginning of the + # configure script would override the LC_ALL setting. Likewise for + # LC_CTYPE, which is also set at the beginning of the configure script. + # Test for the locale name without encoding suffix. + if (LC_ALL=zh_CN LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then + gt_cv_locale_zh_CN=zh_CN else - # If there was a link error, due to mblen(), the system is so old that - # it certainly doesn't have a chinese locale. - gt_cv_locale_zh_CN=none + # Test for the locale name with explicit encoding suffix. + if (LC_ALL=zh_CN.GB18030 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then + gt_cv_locale_zh_CN=zh_CN.GB18030 + else + # None found. + gt_cv_locale_zh_CN=none + fi fi - rm -fr conftest* + else + # If there was a link error, due to mblen(), the system is so old that + # it certainly doesn't have a chinese locale. + gt_cv_locale_zh_CN=none fi + rm -fr conftest* ]) LOCALE_ZH_CN=$gt_cv_locale_zh_CN AC_SUBST([LOCALE_ZH_CN]) diff --git a/m4/longlong.m4 b/m4/longlong.m4 new file mode 100644 index 000000000..eedc8d568 --- /dev/null +++ b/m4/longlong.m4 @@ -0,0 +1,106 @@ +# longlong.m4 serial 14 +dnl Copyright (C) 1999-2007, 2009 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Paul Eggert. + +# Define HAVE_LONG_LONG_INT if 'long long int' works. +# This fixes a bug in Autoconf 2.61, but can be removed once we +# assume 2.62 everywhere. + +# Note: If the type 'long long int' exists but is only 32 bits large +# (as on some very old compilers), HAVE_LONG_LONG_INT will not be +# defined. In this case you can treat 'long long int' like 'long int'. + +AC_DEFUN([AC_TYPE_LONG_LONG_INT], +[ + AC_CACHE_CHECK([for long long int], [ac_cv_type_long_long_int], + [AC_LINK_IFELSE( + [_AC_TYPE_LONG_LONG_SNIPPET], + [dnl This catches a bug in Tandem NonStop Kernel (OSS) cc -O circa 2004. + dnl If cross compiling, assume the bug isn't important, since + dnl nobody cross compiles for this platform as far as we know. + AC_RUN_IFELSE( + [AC_LANG_PROGRAM( + [[@%:@include + @%:@ifndef LLONG_MAX + @%:@ define HALF \ + (1LL << (sizeof (long long int) * CHAR_BIT - 2)) + @%:@ define LLONG_MAX (HALF - 1 + HALF) + @%:@endif]], + [[long long int n = 1; + int i; + for (i = 0; ; i++) + { + long long int m = n << i; + if (m >> i != n) + return 1; + if (LLONG_MAX / 2 < m) + break; + } + return 0;]])], + [ac_cv_type_long_long_int=yes], + [ac_cv_type_long_long_int=no], + [ac_cv_type_long_long_int=yes])], + [ac_cv_type_long_long_int=no])]) + if test $ac_cv_type_long_long_int = yes; then + AC_DEFINE([HAVE_LONG_LONG_INT], [1], + [Define to 1 if the system has the type `long long int'.]) + fi +]) + +# Define HAVE_UNSIGNED_LONG_LONG_INT if 'unsigned long long int' works. +# This fixes a bug in Autoconf 2.61, but can be removed once we +# assume 2.62 everywhere. + +# Note: If the type 'unsigned long long int' exists but is only 32 bits +# large (as on some very old compilers), AC_TYPE_UNSIGNED_LONG_LONG_INT +# will not be defined. In this case you can treat 'unsigned long long int' +# like 'unsigned long int'. + +AC_DEFUN([AC_TYPE_UNSIGNED_LONG_LONG_INT], +[ + AC_CACHE_CHECK([for unsigned long long int], + [ac_cv_type_unsigned_long_long_int], + [AC_LINK_IFELSE( + [_AC_TYPE_LONG_LONG_SNIPPET], + [ac_cv_type_unsigned_long_long_int=yes], + [ac_cv_type_unsigned_long_long_int=no])]) + if test $ac_cv_type_unsigned_long_long_int = yes; then + AC_DEFINE([HAVE_UNSIGNED_LONG_LONG_INT], [1], + [Define to 1 if the system has the type `unsigned long long int'.]) + fi +]) + +# Expands to a C program that can be used to test for simultaneous support +# of 'long long' and 'unsigned long long'. We don't want to say that +# 'long long' is available if 'unsigned long long' is not, or vice versa, +# because too many programs rely on the symmetry between signed and unsigned +# integer types (excluding 'bool'). +AC_DEFUN([_AC_TYPE_LONG_LONG_SNIPPET], +[ + AC_LANG_PROGRAM( + [[/* For now, do not test the preprocessor; as of 2007 there are too many + implementations with broken preprocessors. Perhaps this can + be revisited in 2012. In the meantime, code should not expect + #if to work with literals wider than 32 bits. */ + /* Test literals. */ + long long int ll = 9223372036854775807ll; + long long int nll = -9223372036854775807LL; + unsigned long long int ull = 18446744073709551615ULL; + /* Test constant expressions. */ + typedef int a[((-9223372036854775807LL < 0 && 0 < 9223372036854775807ll) + ? 1 : -1)]; + typedef int b[(18446744073709551615ULL <= (unsigned long long int) -1 + ? 1 : -1)]; + int i = 63;]], + [[/* Test availability of runtime routines for shift and division. */ + long long int llmax = 9223372036854775807ll; + unsigned long long int ullmax = 18446744073709551615ull; + return ((ll << 63) | (ll >> 63) | (ll < i) | (ll > i) + | (llmax / ll) | (llmax % ll) + | (ull << 63) | (ull >> 63) | (ull << i) | (ull >> i) + | (ullmax / ull) | (ullmax % ull));]]) +]) diff --git a/m4/malloc.m4 b/m4/malloc.m4 new file mode 100644 index 000000000..807017166 --- /dev/null +++ b/m4/malloc.m4 @@ -0,0 +1,41 @@ +# malloc.m4 serial 9 +dnl Copyright (C) 2007, 2009 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +# gl_FUNC_MALLOC_POSIX +# -------------------- +# Test whether 'malloc' is POSIX compliant (sets errno to ENOMEM when it +# fails), and replace malloc if it is not. +AC_DEFUN([gl_FUNC_MALLOC_POSIX], +[ + AC_REQUIRE([gl_CHECK_MALLOC_POSIX]) + if test $gl_cv_func_malloc_posix = yes; then + HAVE_MALLOC_POSIX=1 + AC_DEFINE([HAVE_MALLOC_POSIX], [1], + [Define if the 'malloc' function is POSIX compliant.]) + else + AC_LIBOBJ([malloc]) + HAVE_MALLOC_POSIX=0 + fi + AC_SUBST([HAVE_MALLOC_POSIX]) +]) + +# Test whether malloc, realloc, calloc are POSIX compliant, +# Set gl_cv_func_malloc_posix to yes or no accordingly. +AC_DEFUN([gl_CHECK_MALLOC_POSIX], +[ + AC_CACHE_CHECK([whether malloc, realloc, calloc are POSIX compliant], + [gl_cv_func_malloc_posix], + [ + dnl It is too dangerous to try to allocate a large amount of memory: + dnl some systems go to their knees when you do that. So assume that + dnl all Unix implementations of the function are POSIX compliant. + AC_TRY_COMPILE([], + [#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ + choke me + #endif + ], [gl_cv_func_malloc_posix=yes], [gl_cv_func_malloc_posix=no]) + ]) +]) diff --git a/m4/malloca.m4 b/m4/malloca.m4 new file mode 100644 index 000000000..2841ae83a --- /dev/null +++ b/m4/malloca.m4 @@ -0,0 +1,14 @@ +# malloca.m4 serial 1 +dnl Copyright (C) 2003-2004, 2006-2007 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_MALLOCA], +[ + dnl Use the autoconf tests for alloca(), but not the AC_SUBSTed variables + dnl @ALLOCA@ and @LTALLOCA@. + dnl gl_FUNC_ALLOCA dnl Already brought in by the module dependencies. + AC_REQUIRE([gl_EEMALLOC]) + AC_REQUIRE([AC_TYPE_LONG_LONG_INT]) +]) diff --git a/m4/mbrtowc.m4 b/m4/mbrtowc.m4 index da0d426f0..2fddcc8a1 100644 --- a/m4/mbrtowc.m4 +++ b/m4/mbrtowc.m4 @@ -1,5 +1,5 @@ -# mbrtowc.m4 serial 12 -dnl Copyright (C) 2001-2002, 2004-2005, 2008 Free Software Foundation, Inc. +# mbrtowc.m4 serial 16 +dnl Copyright (C) 2001-2002, 2004-2005, 2008, 2009 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. @@ -65,9 +65,15 @@ AC_DEFUN([gl_MBSTATE_T_BROKEN], AC_CHECK_FUNCS_ONCE([mbrtowc]) if test $ac_cv_func_mbsinit = yes && test $ac_cv_func_mbrtowc = yes; then gl_MBRTOWC_INCOMPLETE_STATE + gl_MBRTOWC_SANITYCHECK + REPLACE_MBSTATE_T=0 case "$gl_cv_func_mbrtowc_incomplete_state" in - *yes) REPLACE_MBSTATE_T=0 ;; - *) REPLACE_MBSTATE_T=1 ;; + *yes) ;; + *) REPLACE_MBSTATE_T=1 ;; + esac + case "$gl_cv_func_mbrtowc_sanitycheck" in + *yes) ;; + *) REPLACE_MBSTATE_T=1 ;; esac else REPLACE_MBSTATE_T=1 @@ -121,7 +127,59 @@ int main () }], [gl_cv_func_mbrtowc_incomplete_state=yes], [gl_cv_func_mbrtowc_incomplete_state=no], - []) + [:]) + fi + ]) +]) + +dnl Test whether mbrtowc works not worse than mbtowc. +dnl Result is gl_cv_func_mbrtowc_sanitycheck. + +AC_DEFUN([gl_MBRTOWC_SANITYCHECK], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([gt_LOCALE_ZH_CN]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether mbrtowc works as well as mbtowc], + [gl_cv_func_mbrtowc_sanitycheck], + [ + dnl Initial guess, used when cross-compiling or when no suitable locale + dnl is present. +changequote(,)dnl + case "$host_os" in + # Guess no on Solaris 8. + solaris2.8) gl_cv_func_mbrtowc_sanitycheck="guessing no" ;; + # Guess yes otherwise. + *) gl_cv_func_mbrtowc_sanitycheck="guessing yes" ;; + esac +changequote([,])dnl + if test $LOCALE_ZH_CN != none; then + AC_TRY_RUN([ +#include +#include +#include +#include +int main () +{ + /* This fails on Solaris 8: + mbrtowc returns 2, and sets wc to 0x00F0. + mbtowc returns 4 (correct) and sets wc to 0x5EDC. */ + if (setlocale (LC_ALL, "$LOCALE_ZH_CN") != NULL) + { + char input[] = "B\250\271\201\060\211\070er"; /* "Büßer" */ + mbstate_t state; + wchar_t wc; + + memset (&state, '\0', sizeof (mbstate_t)); + if (mbrtowc (&wc, input + 3, 6, &state) != 4 + && mbtowc (&wc, input + 3, 6) == 4) + return 1; + } + return 0; +}], + [gl_cv_func_mbrtowc_sanitycheck=yes], + [gl_cv_func_mbrtowc_sanitycheck=no], + [:]) fi ]) ]) @@ -168,7 +226,7 @@ int main () return 1; } return 0; -}], [gl_cv_func_mbrtowc_null_arg=yes], [gl_cv_func_mbrtowc_null_arg=no], []) +}], [gl_cv_func_mbrtowc_null_arg=yes], [gl_cv_func_mbrtowc_null_arg=no], [:]) fi ]) ]) @@ -238,7 +296,7 @@ int main () }], [gl_cv_func_mbrtowc_retval=yes], [gl_cv_func_mbrtowc_retval=no], - []) + [:]) fi ]) ]) @@ -258,10 +316,10 @@ AC_DEFUN([gl_MBRTOWC_NUL_RETVAL], dnl is present. changequote(,)dnl case "$host_os" in - # Guess no on Solaris 9. - solaris2.9) gl_cv_func_mbrtowc_nul_retval="guessing no" ;; - # Guess yes otherwise. - *) gl_cv_func_mbrtowc_nul_retval="guessing yes" ;; + # Guess no on Solaris 8 and 9. + solaris2.[89]) gl_cv_func_mbrtowc_nul_retval="guessing no" ;; + # Guess yes otherwise. + *) gl_cv_func_mbrtowc_nul_retval="guessing yes" ;; esac changequote([,])dnl if test $LOCALE_ZH_CN != none; then @@ -271,7 +329,7 @@ changequote([,])dnl #include int main () { - /* This fails on Solaris 9. */ + /* This fails on Solaris 8 and 9. */ if (setlocale (LC_ALL, "$LOCALE_ZH_CN") != NULL) { mbstate_t state; @@ -285,7 +343,7 @@ int main () }], [gl_cv_func_mbrtowc_nul_retval=yes], [gl_cv_func_mbrtowc_nul_retval=no], - []) + [:]) fi ]) ]) @@ -318,7 +376,7 @@ AC_DEFUN([AC_FUNC_MBRTOWC], gl_cv_func_mbrtowc=yes, gl_cv_func_mbrtowc=no)]) if test $gl_cv_func_mbrtowc = yes; then - AC_DEFINE([HAVE_MBRTOWC], 1, + AC_DEFINE([HAVE_MBRTOWC], [1], [Define to 1 if mbrtowc and mbstate_t are properly declared.]) fi ]) diff --git a/m4/mbstate_t.m4 b/m4/mbstate_t.m4 index d2153d9bc..d4ec6f0fc 100644 --- a/m4/mbstate_t.m4 +++ b/m4/mbstate_t.m4 @@ -1,5 +1,5 @@ -# mbstate_t.m4 serial 11 -dnl Copyright (C) 2000-2002, 2008 Free Software Foundation, Inc. +# mbstate_t.m4 serial 12 +dnl Copyright (C) 2000-2002, 2008, 2009 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. @@ -16,7 +16,7 @@ AC_DEFUN([AC_TYPE_MBSTATE_T], [ AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) dnl for HP-UX 11.11 - AC_CACHE_CHECK([for mbstate_t], ac_cv_type_mbstate_t, + AC_CACHE_CHECK([for mbstate_t], [ac_cv_type_mbstate_t], [AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( [AC_INCLUDES_DEFAULT[ @@ -25,10 +25,10 @@ AC_DEFUN([AC_TYPE_MBSTATE_T], [ac_cv_type_mbstate_t=yes], [ac_cv_type_mbstate_t=no])]) if test $ac_cv_type_mbstate_t = yes; then - AC_DEFINE([HAVE_MBSTATE_T], 1, + AC_DEFINE([HAVE_MBSTATE_T], [1], [Define to 1 if declares mbstate_t.]) else - AC_DEFINE([mbstate_t], int, + AC_DEFINE([mbstate_t], [int], [Define to a type if does not define.]) fi ]) diff --git a/m4/memchr.m4 b/m4/memchr.m4 new file mode 100644 index 000000000..1194bac2e --- /dev/null +++ b/m4/memchr.m4 @@ -0,0 +1,86 @@ +# memchr.m4 serial 7 +dnl Copyright (C) 2002, 2003, 2004, 2009 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN_ONCE([gl_FUNC_MEMCHR], +[ + dnl Check for prerequisites for memory fence checks. + gl_FUNC_MMAP_ANON + AC_CHECK_HEADERS_ONCE([sys/mman.h]) + AC_CHECK_FUNCS_ONCE([mprotect]) + + dnl These days, we assume memchr is present. But just in case... + AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS]) + AC_REPLACE_FUNCS([memchr]) + if test $ac_cv_func_memchr = no; then + gl_PREREQ_MEMCHR + REPLACE_MEMCHR=1 + fi + + if test $ac_cv_func_memchr = yes; then + # Detect platform-specific bugs in some versions of glibc: + # memchr should not dereference anything with length 0 + # http://bugzilla.redhat.com/499689 + # memchr should not dereference overestimated length after a match + # http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=521737 + # http://sourceware.org/bugzilla/show_bug.cgi?id=10162 + # Assume that memchr works on platforms that lack mprotect. + AC_CACHE_CHECK([whether memchr works], [gl_cv_func_memchr_works], + [AC_RUN_IFELSE([AC_LANG_PROGRAM([[ +#include +#if HAVE_SYS_MMAN_H +# include +# include +# include +# include +# ifndef MAP_FILE +# define MAP_FILE 0 +# endif +#endif +]], [[ + char *fence = NULL; +#if HAVE_SYS_MMAN_H && HAVE_MPROTECT +# if HAVE_MAP_ANONYMOUS + const int flags = MAP_ANONYMOUS | MAP_PRIVATE; + const int fd = -1; +# else /* !HAVE_MAP_ANONYMOUS */ + const int flags = MAP_FILE | MAP_PRIVATE; + int fd = open ("/dev/zero", O_RDONLY, 0666); + if (fd >= 0) +# endif + { + int pagesize = getpagesize (); + char *two_pages = + (char *) mmap (NULL, 2 * pagesize, PROT_READ | PROT_WRITE, + flags, fd, 0); + if (two_pages != (char *)(-1) + && mprotect (two_pages + pagesize, pagesize, PROT_NONE) == 0) + fence = two_pages + pagesize; + } +#endif + if (fence) + { + if (memchr (fence, 0, 0)) + return 1; + strcpy (fence - 9, "12345678"); + if (memchr (fence - 9, 0, 79) != fence - 1) + return 2; + } + return 0; +]])], [gl_cv_func_memchr_works=yes], [gl_cv_func_memchr_works=no], + [dnl Be pessimistic for now. + gl_cv_func_memchr_works="guessing no"])]) + if test "$gl_cv_func_memchr_works" != yes; then + gl_PREREQ_MEMCHR + REPLACE_MEMCHR=1 + AC_LIBOBJ([memchr]) + fi + fi +]) + +# Prerequisites of lib/memchr.c. +AC_DEFUN([gl_PREREQ_MEMCHR], [ + AC_CHECK_HEADERS([bp-sym.h]) +]) diff --git a/m4/mmap-anon.m4 b/m4/mmap-anon.m4 new file mode 100644 index 000000000..14b6270d2 --- /dev/null +++ b/m4/mmap-anon.m4 @@ -0,0 +1,59 @@ +# mmap-anon.m4 serial 8 +dnl Copyright (C) 2005, 2007, 2009 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +# Detect how mmap can be used to create anonymous (not file-backed) memory +# mappings. +# - On Linux, AIX, OSF/1, Solaris, Cygwin, Interix, Haiku, both MAP_ANONYMOUS +# and MAP_ANON exist and have the same value. +# - On HP-UX, only MAP_ANONYMOUS exists. +# - On MacOS X, FreeBSD, NetBSD, OpenBSD, only MAP_ANON exists. +# - On IRIX, neither exists, and a file descriptor opened to /dev/zero must be +# used. + +AC_DEFUN([gl_FUNC_MMAP_ANON], +[ + dnl Work around a bug of AC_EGREP_CPP in autoconf-2.57. + AC_REQUIRE([AC_PROG_CPP]) + AC_REQUIRE([AC_PROG_EGREP]) + + dnl Persuade glibc to define MAP_ANONYMOUS. + AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) + + # Check for mmap(). Don't use AC_FUNC_MMAP, because it checks too much: it + # fails on HP-UX 11, because MAP_FIXED mappings do not work. But this is + # irrelevant for anonymous mappings. + AC_CHECK_FUNC([mmap], [gl_have_mmap=yes], [gl_have_mmap=no]) + + # Try to allow MAP_ANONYMOUS. + gl_have_mmap_anonymous=no + if test $gl_have_mmap = yes; then + AC_MSG_CHECKING([for MAP_ANONYMOUS]) + AC_EGREP_CPP([I cant identify this map.], [ +#include +#ifdef MAP_ANONYMOUS + I cant identify this map. +#endif +], + [gl_have_mmap_anonymous=yes]) + if test $gl_have_mmap_anonymous != yes; then + AC_EGREP_CPP([I cant identify this map.], [ +#include +#ifdef MAP_ANON + I cant identify this map. +#endif +], + [AC_DEFINE([MAP_ANONYMOUS], [MAP_ANON], + [Define to a substitute value for mmap()'s MAP_ANONYMOUS flag.]) + gl_have_mmap_anonymous=yes]) + fi + AC_MSG_RESULT([$gl_have_mmap_anonymous]) + if test $gl_have_mmap_anonymous = yes; then + AC_DEFINE([HAVE_MAP_ANONYMOUS], [1], + [Define to 1 if mmap()'s MAP_ANONYMOUS flag is available after including + config.h and .]) + fi + fi +]) diff --git a/m4/multiarch.m4 b/m4/multiarch.m4 new file mode 100644 index 000000000..ec377bac8 --- /dev/null +++ b/m4/multiarch.m4 @@ -0,0 +1,65 @@ +# multiarch.m4 serial 5 +dnl Copyright (C) 2008, 2009 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +# Determine whether the compiler is or may be producing universal binaries. +# +# On MacOS X 10.5 and later systems, the user can create libraries and +# executables that work on multiple system types--known as "fat" or +# "universal" binaries--by specifying multiple '-arch' options to the +# compiler but only a single '-arch' option to the preprocessor. Like +# this: +# +# ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ +# CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ +# CPP="gcc -E" CXXCPP="g++ -E" +# +# Detect this situation and set the macro AA_APPLE_UNIVERSAL_BUILD at the +# beginning of config.h and set APPLE_UNIVERSAL_BUILD accordingly. + +AC_DEFUN_ONCE([gl_MULTIARCH], +[ + dnl Code similar to autoconf-2.63 AC_C_BIGENDIAN. + gl_cv_c_multiarch=no + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#ifndef __APPLE_CC__ + not a universal capable compiler + #endif + typedef int dummy; + ]])], + [ + dnl Check for potential -arch flags. It is not universal unless + dnl there are at least two -arch flags with different values. + arch= + prev= + for word in ${CC} ${CFLAGS} ${CPPFLAGS} ${LDFLAGS}; do + if test -n "$prev"; then + case $word in + i?86 | x86_64 | ppc | ppc64) + if test -z "$arch" || test "$arch" = "$word"; then + arch="$word" + else + gl_cv_c_multiarch=yes + fi + ;; + esac + prev= + else + if test "x$word" = "x-arch"; then + prev=arch + fi + fi + done + ]) + if test $gl_cv_c_multiarch = yes; then + AC_DEFINE([AA_APPLE_UNIVERSAL_BUILD], [1], + [Define if the compiler is building for multiple architectures of Apple platforms at once.]) + APPLE_UNIVERSAL_BUILD=1 + else + APPLE_UNIVERSAL_BUILD=0 + fi + AC_SUBST([APPLE_UNIVERSAL_BUILD]) +]) diff --git a/m4/pathmax.m4 b/m4/pathmax.m4 new file mode 100644 index 000000000..465180161 --- /dev/null +++ b/m4/pathmax.m4 @@ -0,0 +1,12 @@ +# pathmax.m4 serial 8 +dnl Copyright (C) 2002, 2003, 2005, 2006, 2009 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_PATHMAX], +[ + dnl Prerequisites of lib/pathmax.h. + AC_CHECK_FUNCS_ONCE([pathconf]) + AC_CHECK_HEADERS_ONCE([sys/param.h]) +]) diff --git a/m4/printf.m4 b/m4/printf.m4 new file mode 100644 index 000000000..87aa45c5e --- /dev/null +++ b/m4/printf.m4 @@ -0,0 +1,1416 @@ +# printf.m4 serial 33 +dnl Copyright (C) 2003, 2007-2009 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl Test whether the *printf family of functions supports the 'j', 'z', 't', +dnl 'L' size specifiers. (ISO C99, POSIX:2001) +dnl Result is gl_cv_func_printf_sizes_c99. + +AC_DEFUN([gl_PRINTF_SIZES_C99], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([gl_AC_HEADER_STDINT_H]) + AC_REQUIRE([gl_AC_HEADER_INTTYPES_H]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether printf supports size specifiers as in C99], + [gl_cv_func_printf_sizes_c99], + [ + AC_TRY_RUN([ +#include +#include +#include +#include +#if HAVE_STDINT_H_WITH_UINTMAX +# include +#endif +#if HAVE_INTTYPES_H_WITH_UINTMAX +# include +#endif +static char buf[100]; +int main () +{ +#if HAVE_STDINT_H_WITH_UINTMAX || HAVE_INTTYPES_H_WITH_UINTMAX + buf[0] = '\0'; + if (sprintf (buf, "%ju %d", (uintmax_t) 12345671, 33, 44, 55) < 0 + || strcmp (buf, "12345671 33") != 0) + return 1; +#endif + buf[0] = '\0'; + if (sprintf (buf, "%zu %d", (size_t) 12345672, 33, 44, 55) < 0 + || strcmp (buf, "12345672 33") != 0) + return 1; + buf[0] = '\0'; + if (sprintf (buf, "%tu %d", (ptrdiff_t) 12345673, 33, 44, 55) < 0 + || strcmp (buf, "12345673 33") != 0) + return 1; + buf[0] = '\0'; + if (sprintf (buf, "%Lg %d", (long double) 1.5, 33, 44, 55) < 0 + || strcmp (buf, "1.5 33") != 0) + return 1; + return 0; +}], [gl_cv_func_printf_sizes_c99=yes], [gl_cv_func_printf_sizes_c99=no], + [ +changequote(,)dnl + case "$host_os" in + # Guess yes on glibc systems. + *-gnu*) gl_cv_func_printf_sizes_c99="guessing yes";; + # Guess yes on FreeBSD >= 5. + freebsd[1-4]*) gl_cv_func_printf_sizes_c99="guessing no";; + freebsd* | kfreebsd*) gl_cv_func_printf_sizes_c99="guessing yes";; + # Guess yes on MacOS X >= 10.3. + darwin[1-6].*) gl_cv_func_printf_sizes_c99="guessing no";; + darwin*) gl_cv_func_printf_sizes_c99="guessing yes";; + # Guess yes on OpenBSD >= 3.9. + openbsd[1-2].* | openbsd3.[0-8] | openbsd3.[0-8].*) + gl_cv_func_printf_sizes_c99="guessing no";; + openbsd*) gl_cv_func_printf_sizes_c99="guessing yes";; + # Guess yes on Solaris >= 2.10. + solaris2.[0-9]*) gl_cv_func_printf_sizes_c99="guessing no";; + solaris*) gl_cv_func_printf_sizes_c99="guessing yes";; + # Guess yes on NetBSD >= 3. + netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*) + gl_cv_func_printf_sizes_c99="guessing no";; + netbsd*) gl_cv_func_printf_sizes_c99="guessing yes";; + # If we don't know, assume the worst. + *) gl_cv_func_printf_sizes_c99="guessing no";; + esac +changequote([,])dnl + ]) + ]) +]) + +dnl Test whether the *printf family of functions supports 'long double' +dnl arguments together with the 'L' size specifier. (ISO C99, POSIX:2001) +dnl Result is gl_cv_func_printf_long_double. + +AC_DEFUN([gl_PRINTF_LONG_DOUBLE], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether printf supports 'long double' arguments], + [gl_cv_func_printf_long_double], + [ + AC_TRY_RUN([ +#include +#include +static char buf[10000]; +int main () +{ + buf[0] = '\0'; + if (sprintf (buf, "%Lf %d", 1.75L, 33, 44, 55) < 0 + || strcmp (buf, "1.750000 33") != 0) + return 1; + buf[0] = '\0'; + if (sprintf (buf, "%Le %d", 1.75L, 33, 44, 55) < 0 + || strcmp (buf, "1.750000e+00 33") != 0) + return 1; + buf[0] = '\0'; + if (sprintf (buf, "%Lg %d", 1.75L, 33, 44, 55) < 0 + || strcmp (buf, "1.75 33") != 0) + return 1; + return 0; +}], [gl_cv_func_printf_long_double=yes], [gl_cv_func_printf_long_double=no], + [ +changequote(,)dnl + case "$host_os" in + beos*) gl_cv_func_printf_long_double="guessing no";; + mingw* | pw*) gl_cv_func_printf_long_double="guessing no";; + *) gl_cv_func_printf_long_double="guessing yes";; + esac +changequote([,])dnl + ]) + ]) +]) + +dnl Test whether the *printf family of functions supports infinite and NaN +dnl 'double' arguments and negative zero arguments in the %f, %e, %g +dnl directives. (ISO C99, POSIX:2001) +dnl Result is gl_cv_func_printf_infinite. + +AC_DEFUN([gl_PRINTF_INFINITE], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether printf supports infinite 'double' arguments], + [gl_cv_func_printf_infinite], + [ + AC_TRY_RUN([ +#include +#include +static int +strisnan (const char *string, size_t start_index, size_t end_index) +{ + if (start_index < end_index) + { + if (string[start_index] == '-') + start_index++; + if (start_index + 3 <= end_index + && memcmp (string + start_index, "nan", 3) == 0) + { + start_index += 3; + if (start_index == end_index + || (string[start_index] == '(' && string[end_index - 1] == ')')) + return 1; + } + } + return 0; +} +static int +have_minus_zero () +{ + static double plus_zero = 0.0; + double minus_zero = - plus_zero; + return memcmp (&plus_zero, &minus_zero, sizeof (double)) != 0; +} +static char buf[10000]; +static double zero = 0.0; +int main () +{ + if (sprintf (buf, "%f", 1.0 / 0.0) < 0 + || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0)) + return 1; + if (sprintf (buf, "%f", -1.0 / 0.0) < 0 + || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0)) + return 1; + if (sprintf (buf, "%f", zero / zero) < 0 + || !strisnan (buf, 0, strlen (buf))) + return 1; + if (sprintf (buf, "%e", 1.0 / 0.0) < 0 + || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0)) + return 1; + if (sprintf (buf, "%e", -1.0 / 0.0) < 0 + || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0)) + return 1; + if (sprintf (buf, "%e", zero / zero) < 0 + || !strisnan (buf, 0, strlen (buf))) + return 1; + if (sprintf (buf, "%g", 1.0 / 0.0) < 0 + || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0)) + return 1; + if (sprintf (buf, "%g", -1.0 / 0.0) < 0 + || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0)) + return 1; + if (sprintf (buf, "%g", zero / zero) < 0 + || !strisnan (buf, 0, strlen (buf))) + return 1; + /* This test fails on HP-UX 10.20. */ + if (have_minus_zero ()) + if (sprintf (buf, "%g", - zero) < 0 + || strcmp (buf, "-0") != 0) + return 1; + return 0; +}], [gl_cv_func_printf_infinite=yes], [gl_cv_func_printf_infinite=no], + [ +changequote(,)dnl + case "$host_os" in + # Guess yes on glibc systems. + *-gnu*) gl_cv_func_printf_infinite="guessing yes";; + # Guess yes on FreeBSD >= 6. + freebsd[1-5]*) gl_cv_func_printf_infinite="guessing no";; + freebsd* | kfreebsd*) gl_cv_func_printf_infinite="guessing yes";; + # Guess yes on MacOS X >= 10.3. + darwin[1-6].*) gl_cv_func_printf_infinite="guessing no";; + darwin*) gl_cv_func_printf_infinite="guessing yes";; + # Guess yes on HP-UX >= 11. + hpux[7-9]* | hpux10*) gl_cv_func_printf_infinite="guessing no";; + hpux*) gl_cv_func_printf_infinite="guessing yes";; + # Guess yes on NetBSD >= 3. + netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*) + gl_cv_func_printf_infinite="guessing no";; + netbsd*) gl_cv_func_printf_infinite="guessing yes";; + # Guess yes on BeOS. + beos*) gl_cv_func_printf_infinite="guessing yes";; + # If we don't know, assume the worst. + *) gl_cv_func_printf_infinite="guessing no";; + esac +changequote([,])dnl + ]) + ]) +]) + +dnl Test whether the *printf family of functions supports infinite and NaN +dnl 'long double' arguments in the %f, %e, %g directives. (ISO C99, POSIX:2001) +dnl Result is gl_cv_func_printf_infinite_long_double. + +AC_DEFUN([gl_PRINTF_INFINITE_LONG_DOUBLE], +[ + AC_REQUIRE([gl_PRINTF_LONG_DOUBLE]) + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([gl_BIGENDIAN]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + dnl The user can set or unset the variable gl_printf_safe to indicate + dnl that he wishes a safe handling of non-IEEE-754 'long double' values. + if test -n "$gl_printf_safe"; then + AC_DEFINE([CHECK_PRINTF_SAFE], [1], + [Define if you wish *printf() functions that have a safe handling of + non-IEEE-754 'long double' values.]) + fi + case "$gl_cv_func_printf_long_double" in + *yes) + AC_CACHE_CHECK([whether printf supports infinite 'long double' arguments], + [gl_cv_func_printf_infinite_long_double], + [ + AC_TRY_RUN([ +]GL_NOCRASH[ +#include +#include +#include +static int +strisnan (const char *string, size_t start_index, size_t end_index) +{ + if (start_index < end_index) + { + if (string[start_index] == '-') + start_index++; + if (start_index + 3 <= end_index + && memcmp (string + start_index, "nan", 3) == 0) + { + start_index += 3; + if (start_index == end_index + || (string[start_index] == '(' && string[end_index - 1] == ')')) + return 1; + } + } + return 0; +} +static char buf[10000]; +static long double zeroL = 0.0L; +int main () +{ + nocrash_init(); + if (sprintf (buf, "%Lf", 1.0L / 0.0L) < 0 + || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0)) + return 1; + if (sprintf (buf, "%Lf", -1.0L / 0.0L) < 0 + || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0)) + return 1; + if (sprintf (buf, "%Lf", zeroL / zeroL) < 0 + || !strisnan (buf, 0, strlen (buf))) + return 1; + if (sprintf (buf, "%Le", 1.0L / 0.0L) < 0 + || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0)) + return 1; + if (sprintf (buf, "%Le", -1.0L / 0.0L) < 0 + || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0)) + return 1; + if (sprintf (buf, "%Le", zeroL / zeroL) < 0 + || !strisnan (buf, 0, strlen (buf))) + return 1; + if (sprintf (buf, "%Lg", 1.0L / 0.0L) < 0 + || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0)) + return 1; + if (sprintf (buf, "%Lg", -1.0L / 0.0L) < 0 + || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0)) + return 1; + if (sprintf (buf, "%Lg", zeroL / zeroL) < 0 + || !strisnan (buf, 0, strlen (buf))) + return 1; +#if CHECK_PRINTF_SAFE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_)) +/* Representation of an 80-bit 'long double' as an initializer for a sequence + of 'unsigned int' words. */ +# ifdef WORDS_BIGENDIAN +# define LDBL80_WORDS(exponent,manthi,mantlo) \ + { ((unsigned int) (exponent) << 16) | ((unsigned int) (manthi) >> 16), \ + ((unsigned int) (manthi) << 16) | (unsigned int) (mantlo) >> 16), \ + (unsigned int) (mantlo) << 16 \ + } +# else +# define LDBL80_WORDS(exponent,manthi,mantlo) \ + { mantlo, manthi, exponent } +# endif + { /* Quiet NaN. */ + static union { unsigned int word[4]; long double value; } x = + { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) }; + if (sprintf (buf, "%Lf", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) + return 1; + if (sprintf (buf, "%Le", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) + return 1; + if (sprintf (buf, "%Lg", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) + return 1; + } + { + /* Signalling NaN. */ + static union { unsigned int word[4]; long double value; } x = + { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) }; + if (sprintf (buf, "%Lf", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) + return 1; + if (sprintf (buf, "%Le", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) + return 1; + if (sprintf (buf, "%Lg", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) + return 1; + } + { /* Pseudo-NaN. */ + static union { unsigned int word[4]; long double value; } x = + { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) }; + if (sprintf (buf, "%Lf", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) + return 1; + if (sprintf (buf, "%Le", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) + return 1; + if (sprintf (buf, "%Lg", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) + return 1; + } + { /* Pseudo-Infinity. */ + static union { unsigned int word[4]; long double value; } x = + { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) }; + if (sprintf (buf, "%Lf", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) + return 1; + if (sprintf (buf, "%Le", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) + return 1; + if (sprintf (buf, "%Lg", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) + return 1; + } + { /* Pseudo-Zero. */ + static union { unsigned int word[4]; long double value; } x = + { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) }; + if (sprintf (buf, "%Lf", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) + return 1; + if (sprintf (buf, "%Le", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) + return 1; + if (sprintf (buf, "%Lg", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) + return 1; + } + { /* Unnormalized number. */ + static union { unsigned int word[4]; long double value; } x = + { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) }; + if (sprintf (buf, "%Lf", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) + return 1; + if (sprintf (buf, "%Le", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) + return 1; + if (sprintf (buf, "%Lg", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) + return 1; + } + { /* Pseudo-Denormal. */ + static union { unsigned int word[4]; long double value; } x = + { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) }; + if (sprintf (buf, "%Lf", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) + return 1; + if (sprintf (buf, "%Le", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) + return 1; + if (sprintf (buf, "%Lg", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) + return 1; + } +#endif + return 0; +}], + [gl_cv_func_printf_infinite_long_double=yes], + [gl_cv_func_printf_infinite_long_double=no], + [ +changequote(,)dnl + case "$host_cpu" in + # Guess no on ia64, x86_64, i386. + ia64 | x86_64 | i*86) gl_cv_func_printf_infinite_long_double="guessing no";; + *) + case "$host_os" in + # Guess yes on glibc systems. + *-gnu*) gl_cv_func_printf_infinite_long_double="guessing yes";; + # Guess yes on FreeBSD >= 6. + freebsd[1-5]*) gl_cv_func_printf_infinite_long_double="guessing no";; + freebsd* | kfreebsd*) gl_cv_func_printf_infinite_long_double="guessing yes";; + # Guess yes on MacOS X >= 10.3. + darwin[1-6].*) gl_cv_func_printf_infinite_long_double="guessing no";; + darwin*) gl_cv_func_printf_infinite_long_double="guessing yes";; + # Guess yes on HP-UX >= 11. + hpux[7-9]* | hpux10*) gl_cv_func_printf_infinite_long_double="guessing no";; + hpux*) gl_cv_func_printf_infinite_long_double="guessing yes";; + # Guess yes on NetBSD >= 3. + netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*) + gl_cv_func_printf_infinite_long_double="guessing no";; + netbsd*) gl_cv_func_printf_infinite_long_double="guessing yes";; + # If we don't know, assume the worst. + *) gl_cv_func_printf_infinite_long_double="guessing no";; + esac + ;; + esac +changequote([,])dnl + ]) + ]) + ;; + *) + gl_cv_func_printf_infinite_long_double="irrelevant" + ;; + esac +]) + +dnl Test whether the *printf family of functions supports the 'a' and 'A' +dnl conversion specifier for hexadecimal output of floating-point numbers. +dnl (ISO C99, POSIX:2001) +dnl Result is gl_cv_func_printf_directive_a. + +AC_DEFUN([gl_PRINTF_DIRECTIVE_A], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether printf supports the 'a' and 'A' directives], + [gl_cv_func_printf_directive_a], + [ + AC_TRY_RUN([ +#include +#include +static char buf[100]; +int main () +{ + if (sprintf (buf, "%a %d", 3.1416015625, 33, 44, 55) < 0 + || (strcmp (buf, "0x1.922p+1 33") != 0 + && strcmp (buf, "0x3.244p+0 33") != 0 + && strcmp (buf, "0x6.488p-1 33") != 0 + && strcmp (buf, "0xc.91p-2 33") != 0)) + return 1; + if (sprintf (buf, "%A %d", -3.1416015625, 33, 44, 55) < 0 + || (strcmp (buf, "-0X1.922P+1 33") != 0 + && strcmp (buf, "-0X3.244P+0 33") != 0 + && strcmp (buf, "-0X6.488P-1 33") != 0 + && strcmp (buf, "-0XC.91P-2 33") != 0)) + return 1; + /* This catches a FreeBSD 6.1 bug: it doesn't round. */ + if (sprintf (buf, "%.2a %d", 1.51, 33, 44, 55) < 0 + || (strcmp (buf, "0x1.83p+0 33") != 0 + && strcmp (buf, "0x3.05p-1 33") != 0 + && strcmp (buf, "0x6.0ap-2 33") != 0 + && strcmp (buf, "0xc.14p-3 33") != 0)) + return 1; + /* This catches a FreeBSD 6.1 bug. See + */ + if (sprintf (buf, "%010a %d", 1.0 / 0.0, 33, 44, 55) < 0 + || buf[0] == '0') + return 1; + /* This catches a MacOS X 10.3.9 (Darwin 7.9) bug. */ + if (sprintf (buf, "%.1a", 1.999) < 0 + || (strcmp (buf, "0x1.0p+1") != 0 + && strcmp (buf, "0x2.0p+0") != 0 + && strcmp (buf, "0x4.0p-1") != 0 + && strcmp (buf, "0x8.0p-2") != 0)) + return 1; + /* This catches the same MacOS X 10.3.9 (Darwin 7.9) bug and also a + glibc 2.4 bug . */ + if (sprintf (buf, "%.1La", 1.999L) < 0 + || (strcmp (buf, "0x1.0p+1") != 0 + && strcmp (buf, "0x2.0p+0") != 0 + && strcmp (buf, "0x4.0p-1") != 0 + && strcmp (buf, "0x8.0p-2") != 0)) + return 1; + return 0; +}], [gl_cv_func_printf_directive_a=yes], [gl_cv_func_printf_directive_a=no], + [ + case "$host_os" in + # Guess yes on glibc >= 2.5 systems. + *-gnu*) + AC_EGREP_CPP([BZ2908], [ + #include + #ifdef __GNU_LIBRARY__ + #if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 5) || (__GLIBC__ > 2) + BZ2908 + #endif + #endif + ], + [gl_cv_func_printf_directive_a="guessing yes"], + [gl_cv_func_printf_directive_a="guessing no"]) + ;; + # If we don't know, assume the worst. + *) gl_cv_func_printf_directive_a="guessing no";; + esac + ]) + ]) +]) + +dnl Test whether the *printf family of functions supports the %F format +dnl directive. (ISO C99, POSIX:2001) +dnl Result is gl_cv_func_printf_directive_f. + +AC_DEFUN([gl_PRINTF_DIRECTIVE_F], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether printf supports the 'F' directive], + [gl_cv_func_printf_directive_f], + [ + AC_TRY_RUN([ +#include +#include +static char buf[100]; +int main () +{ + if (sprintf (buf, "%F %d", 1234567.0, 33, 44, 55) < 0 + || strcmp (buf, "1234567.000000 33") != 0) + return 1; + if (sprintf (buf, "%F", 1.0 / 0.0) < 0 + || (strcmp (buf, "INF") != 0 && strcmp (buf, "INFINITY") != 0)) + return 1; + /* This catches a Cygwin 1.5.x bug. */ + if (sprintf (buf, "%.F", 1234.0) < 0 + || strcmp (buf, "1234") != 0) + return 1; + return 0; +}], [gl_cv_func_printf_directive_f=yes], [gl_cv_func_printf_directive_f=no], + [ +changequote(,)dnl + case "$host_os" in + # Guess yes on glibc systems. + *-gnu*) gl_cv_func_printf_directive_f="guessing yes";; + # Guess yes on FreeBSD >= 6. + freebsd[1-5]*) gl_cv_func_printf_directive_f="guessing no";; + freebsd* | kfreebsd*) gl_cv_func_printf_directive_f="guessing yes";; + # Guess yes on MacOS X >= 10.3. + darwin[1-6].*) gl_cv_func_printf_directive_f="guessing no";; + darwin*) gl_cv_func_printf_directive_f="guessing yes";; + # Guess yes on Solaris >= 2.10. + solaris2.[0-9]*) gl_cv_func_printf_directive_f="guessing no";; + solaris*) gl_cv_func_printf_directive_f="guessing yes";; + # If we don't know, assume the worst. + *) gl_cv_func_printf_directive_f="guessing no";; + esac +changequote([,])dnl + ]) + ]) +]) + +dnl Test whether the *printf family of functions supports the %n format +dnl directive. (ISO C99, POSIX:2001) +dnl Result is gl_cv_func_printf_directive_n. + +AC_DEFUN([gl_PRINTF_DIRECTIVE_N], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether printf supports the 'n' directive], + [gl_cv_func_printf_directive_n], + [ + AC_TRY_RUN([ +#include +#include +static char fmtstring[10]; +static char buf[100]; +int main () +{ + int count = -1; + /* Copy the format string. Some systems (glibc with _FORTIFY_SOURCE=2) + support %n in format strings in read-only memory but not in writable + memory. */ + strcpy (fmtstring, "%d %n"); + if (sprintf (buf, fmtstring, 123, &count, 33, 44, 55) < 0 + || strcmp (buf, "123 ") != 0 + || count != 4) + return 1; + return 0; +}], [gl_cv_func_printf_directive_n=yes], [gl_cv_func_printf_directive_n=no], + [ +changequote(,)dnl + case "$host_os" in + *) gl_cv_func_printf_directive_n="guessing yes";; + esac +changequote([,])dnl + ]) + ]) +]) + +dnl Test whether the *printf family of functions supports the %ls format +dnl directive and in particular, when a precision is specified, whether +dnl the functions stop converting the wide string argument when the number +dnl of bytes that have been produced by this conversion equals or exceeds +dnl the precision. +dnl Result is gl_cv_func_printf_directive_ls. + +AC_DEFUN([gl_PRINTF_DIRECTIVE_LS], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether printf supports the 'ls' directive], + [gl_cv_func_printf_directive_ls], + [ + AC_TRY_RUN([ +/* Tru64 with Desktop Toolkit C has a bug: must be included before + . + BSD/OS 4.0.1 has a bug: , and must be + included before . */ +#include +#include +#include +#include +#include +int main () +{ + char buf[100]; + /* Test whether %ls works at all. + This test fails on OpenBSD 4.0, IRIX 6.5, Solaris 2.6, Haiku, but not on + Cygwin 1.5. */ + { + static const wchar_t wstring[] = { 'a', 'b', 'c', 0 }; + buf[0] = '\0'; + if (sprintf (buf, "%ls", wstring) < 0 + || strcmp (buf, "abc") != 0) + return 1; + } + /* This test fails on IRIX 6.5, Solaris 2.6, Cygwin 1.5, Haiku (with an + assertion failure inside libc), but not on OpenBSD 4.0. */ + { + static const wchar_t wstring[] = { 'a', 0 }; + buf[0] = '\0'; + if (sprintf (buf, "%ls", wstring) < 0 + || strcmp (buf, "a") != 0) + return 1; + } + /* Test whether precisions in %ls are supported as specified in ISO C 99 + section 7.19.6.1: + "If a precision is specified, no more than that many bytes are written + (including shift sequences, if any), and the array shall contain a + null wide character if, to equal the multibyte character sequence + length given by the precision, the function would need to access a + wide character one past the end of the array." + This test fails on Solaris 10. */ + { + static const wchar_t wstring[] = { 'a', 'b', (wchar_t) 0xfdfdfdfd, 0 }; + buf[0] = '\0'; + if (sprintf (buf, "%.2ls", wstring) < 0 + || strcmp (buf, "ab") != 0) + return 1; + } + return 0; +}], [gl_cv_func_printf_directive_ls=yes], [gl_cv_func_printf_directive_ls=no], + [ +changequote(,)dnl + case "$host_os" in + openbsd*) gl_cv_func_printf_directive_ls="guessing no";; + irix*) gl_cv_func_printf_directive_ls="guessing no";; + solaris*) gl_cv_func_printf_directive_ls="guessing no";; + cygwin*) gl_cv_func_printf_directive_ls="guessing no";; + beos* | haiku*) gl_cv_func_printf_directive_ls="guessing no";; + *) gl_cv_func_printf_directive_ls="guessing yes";; + esac +changequote([,])dnl + ]) + ]) +]) + +dnl Test whether the *printf family of functions supports POSIX/XSI format +dnl strings with positions. (POSIX:2001) +dnl Result is gl_cv_func_printf_positions. + +AC_DEFUN([gl_PRINTF_POSITIONS], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether printf supports POSIX/XSI format strings with positions], + [gl_cv_func_printf_positions], + [ + AC_TRY_RUN([ +#include +#include +/* The string "%2$d %1$d", with dollar characters protected from the shell's + dollar expansion (possibly an autoconf bug). */ +static char format[] = { '%', '2', '$', 'd', ' ', '%', '1', '$', 'd', '\0' }; +static char buf[100]; +int main () +{ + sprintf (buf, format, 33, 55); + return (strcmp (buf, "55 33") != 0); +}], [gl_cv_func_printf_positions=yes], [gl_cv_func_printf_positions=no], + [ +changequote(,)dnl + case "$host_os" in + netbsd[1-3]* | netbsdelf[1-3]* | netbsdaout[1-3]* | netbsdcoff[1-3]*) + gl_cv_func_printf_positions="guessing no";; + beos*) gl_cv_func_printf_positions="guessing no";; + mingw* | pw*) gl_cv_func_printf_positions="guessing no";; + *) gl_cv_func_printf_positions="guessing yes";; + esac +changequote([,])dnl + ]) + ]) +]) + +dnl Test whether the *printf family of functions supports POSIX/XSI format +dnl strings with the ' flag for grouping of decimal digits. (POSIX:2001) +dnl Result is gl_cv_func_printf_flag_grouping. + +AC_DEFUN([gl_PRINTF_FLAG_GROUPING], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether printf supports the grouping flag], + [gl_cv_func_printf_flag_grouping], + [ + AC_TRY_RUN([ +#include +#include +static char buf[100]; +int main () +{ + if (sprintf (buf, "%'d %d", 1234567, 99) < 0 + || buf[strlen (buf) - 1] != '9') + return 1; + return 0; +}], [gl_cv_func_printf_flag_grouping=yes], [gl_cv_func_printf_flag_grouping=no], + [ +changequote(,)dnl + case "$host_os" in + cygwin*) gl_cv_func_printf_flag_grouping="guessing no";; + netbsd*) gl_cv_func_printf_flag_grouping="guessing no";; + mingw* | pw*) gl_cv_func_printf_flag_grouping="guessing no";; + *) gl_cv_func_printf_flag_grouping="guessing yes";; + esac +changequote([,])dnl + ]) + ]) +]) + +dnl Test whether the *printf family of functions supports the - flag correctly. +dnl (ISO C99.) See +dnl +dnl Result is gl_cv_func_printf_flag_leftadjust. + +AC_DEFUN([gl_PRINTF_FLAG_LEFTADJUST], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether printf supports the left-adjust flag correctly], + [gl_cv_func_printf_flag_leftadjust], + [ + AC_TRY_RUN([ +#include +#include +static char buf[100]; +int main () +{ + /* Check that a '-' flag is not annihilated by a negative width. */ + if (sprintf (buf, "a%-*sc", -3, "b") < 0 + || strcmp (buf, "ab c") != 0) + return 1; + return 0; +}], + [gl_cv_func_printf_flag_leftadjust=yes], + [gl_cv_func_printf_flag_leftadjust=no], + [ +changequote(,)dnl + case "$host_os" in + # Guess yes on HP-UX 11. + hpux11*) gl_cv_func_printf_flag_leftadjust="guessing yes";; + # Guess no on HP-UX 10 and older. + hpux*) gl_cv_func_printf_flag_leftadjust="guessing no";; + # Guess yes otherwise. + *) gl_cv_func_printf_flag_leftadjust="guessing yes";; + esac +changequote([,])dnl + ]) + ]) +]) + +dnl Test whether the *printf family of functions supports padding of non-finite +dnl values with the 0 flag correctly. (ISO C99 + TC1 + TC2.) See +dnl +dnl Result is gl_cv_func_printf_flag_zero. + +AC_DEFUN([gl_PRINTF_FLAG_ZERO], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether printf supports the zero flag correctly], + [gl_cv_func_printf_flag_zero], + [ + AC_TRY_RUN([ +#include +#include +static char buf[100]; +int main () +{ + if (sprintf (buf, "%010f", 1.0 / 0.0, 33, 44, 55) < 0 + || (strcmp (buf, " inf") != 0 + && strcmp (buf, " infinity") != 0)) + return 1; + return 0; +}], [gl_cv_func_printf_flag_zero=yes], [gl_cv_func_printf_flag_zero=no], + [ +changequote(,)dnl + case "$host_os" in + # Guess yes on glibc systems. + *-gnu*) gl_cv_func_printf_flag_zero="guessing yes";; + # Guess yes on BeOS. + beos*) gl_cv_func_printf_flag_zero="guessing yes";; + # If we don't know, assume the worst. + *) gl_cv_func_printf_flag_zero="guessing no";; + esac +changequote([,])dnl + ]) + ]) +]) + +dnl Test whether the *printf family of functions supports large precisions. +dnl On mingw, precisions larger than 512 are treated like 512, in integer, +dnl floating-point or pointer output. On BeOS, precisions larger than 1044 +dnl crash the program. +dnl Result is gl_cv_func_printf_precision. + +AC_DEFUN([gl_PRINTF_PRECISION], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether printf supports large precisions], + [gl_cv_func_printf_precision], + [ + AC_TRY_RUN([ +#include +#include +static char buf[5000]; +int main () +{ +#ifdef __BEOS__ + /* On BeOS, this would crash and show a dialog box. Avoid the crash. */ + return 1; +#endif + if (sprintf (buf, "%.4000d %d", 1, 33, 44) < 4000 + 3) + return 1; + return 0; +}], [gl_cv_func_printf_precision=yes], [gl_cv_func_printf_precision=no], + [ +changequote(,)dnl + case "$host_os" in + # Guess no only on native Win32 and BeOS systems. + mingw* | pw*) gl_cv_func_printf_precision="guessing no" ;; + beos*) gl_cv_func_printf_precision="guessing no" ;; + *) gl_cv_func_printf_precision="guessing yes" ;; + esac +changequote([,])dnl + ]) + ]) +]) + +dnl Test whether the *printf family of functions recovers gracefully in case +dnl of an out-of-memory condition, or whether it crashes the entire program. +dnl Result is gl_cv_func_printf_enomem. + +AC_DEFUN([gl_PRINTF_ENOMEM], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([gl_MULTIARCH]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether printf survives out-of-memory conditions], + [gl_cv_func_printf_enomem], + [ + gl_cv_func_printf_enomem="guessing no" + if test "$cross_compiling" = no; then + if test $APPLE_UNIVERSAL_BUILD = 0; then + AC_LANG_CONFTEST([AC_LANG_SOURCE([ +]GL_NOCRASH[ +changequote(,)dnl +#include +#include +#include +#include +#include +int main() +{ + struct rlimit limit; + int ret; + nocrash_init (); + /* Some printf implementations allocate temporary space with malloc. */ + /* On BSD systems, malloc() is limited by RLIMIT_DATA. */ +#ifdef RLIMIT_DATA + if (getrlimit (RLIMIT_DATA, &limit) < 0) + return 77; + if (limit.rlim_max == RLIM_INFINITY || limit.rlim_max > 5000000) + limit.rlim_max = 5000000; + limit.rlim_cur = limit.rlim_max; + if (setrlimit (RLIMIT_DATA, &limit) < 0) + return 77; +#endif + /* On Linux systems, malloc() is limited by RLIMIT_AS. */ +#ifdef RLIMIT_AS + if (getrlimit (RLIMIT_AS, &limit) < 0) + return 77; + if (limit.rlim_max == RLIM_INFINITY || limit.rlim_max > 5000000) + limit.rlim_max = 5000000; + limit.rlim_cur = limit.rlim_max; + if (setrlimit (RLIMIT_AS, &limit) < 0) + return 77; +#endif + /* Some printf implementations allocate temporary space on the stack. */ +#ifdef RLIMIT_STACK + if (getrlimit (RLIMIT_STACK, &limit) < 0) + return 77; + if (limit.rlim_max == RLIM_INFINITY || limit.rlim_max > 5000000) + limit.rlim_max = 5000000; + limit.rlim_cur = limit.rlim_max; + if (setrlimit (RLIMIT_STACK, &limit) < 0) + return 77; +#endif + ret = printf ("%.5000000f", 1.0); + return !(ret == 5000002 || (ret < 0 && errno == ENOMEM)); +} +changequote([,])dnl + ])]) + if AC_TRY_EVAL([ac_link]) && test -s conftest$ac_exeext; then + (./conftest + result=$? + if test $result != 0 && test $result != 77; then result=1; fi + exit $result + ) >/dev/null 2>/dev/null + case $? in + 0) gl_cv_func_printf_enomem="yes" ;; + 77) gl_cv_func_printf_enomem="guessing no" ;; + *) gl_cv_func_printf_enomem="no" ;; + esac + else + gl_cv_func_printf_enomem="guessing no" + fi + rm -fr conftest* + else + dnl A universal build on Apple MacOS X platforms. + dnl The result would be 'no' in 32-bit mode and 'yes' in 64-bit mode. + dnl But we need a configuration result that is valid in both modes. + gl_cv_func_printf_enomem="guessing no" + fi + fi + if test "$gl_cv_func_printf_enomem" = "guessing no"; then +changequote(,)dnl + case "$host_os" in + # Guess yes on glibc systems. + *-gnu*) gl_cv_func_printf_enomem="guessing yes";; + # Guess yes on Solaris. + solaris*) gl_cv_func_printf_enomem="guessing yes";; + # Guess yes on AIX. + aix*) gl_cv_func_printf_enomem="guessing yes";; + # Guess yes on HP-UX/hppa. + hpux*) case "$host_cpu" in + hppa*) gl_cv_func_printf_enomem="guessing yes";; + *) gl_cv_func_printf_enomem="guessing no";; + esac + ;; + # Guess yes on IRIX. + irix*) gl_cv_func_printf_enomem="guessing yes";; + # Guess yes on OSF/1. + osf*) gl_cv_func_printf_enomem="guessing yes";; + # Guess yes on BeOS. + beos*) gl_cv_func_printf_enomem="guessing yes";; + # Guess yes on Haiku. + haiku*) gl_cv_func_printf_enomem="guessing yes";; + # If we don't know, assume the worst. + *) gl_cv_func_printf_enomem="guessing no";; + esac +changequote([,])dnl + fi + ]) +]) + +dnl Test whether the snprintf function exists. (ISO C99, POSIX:2001) +dnl Result is ac_cv_func_snprintf. + +AC_DEFUN([gl_SNPRINTF_PRESENCE], +[ + AC_CHECK_FUNCS_ONCE([snprintf]) +]) + +dnl Test whether the string produced by the snprintf function is always NUL +dnl terminated. (ISO C99, POSIX:2001) +dnl Result is gl_cv_func_snprintf_truncation_c99. + +AC_DEFUN([gl_SNPRINTF_TRUNCATION_C99], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether snprintf truncates the result as in C99], + [gl_cv_func_snprintf_truncation_c99], + [ + AC_TRY_RUN([ +#include +#include +static char buf[100]; +int main () +{ + strcpy (buf, "ABCDEF"); + snprintf (buf, 3, "%d %d", 4567, 89); + if (memcmp (buf, "45\0DEF", 6) != 0) + return 1; + return 0; +}], [gl_cv_func_snprintf_truncation_c99=yes], [gl_cv_func_snprintf_truncation_c99=no], + [ +changequote(,)dnl + case "$host_os" in + # Guess yes on glibc systems. + *-gnu*) gl_cv_func_snprintf_truncation_c99="guessing yes";; + # Guess yes on FreeBSD >= 5. + freebsd[1-4]*) gl_cv_func_snprintf_truncation_c99="guessing no";; + freebsd* | kfreebsd*) gl_cv_func_snprintf_truncation_c99="guessing yes";; + # Guess yes on MacOS X >= 10.3. + darwin[1-6].*) gl_cv_func_snprintf_truncation_c99="guessing no";; + darwin*) gl_cv_func_snprintf_truncation_c99="guessing yes";; + # Guess yes on OpenBSD >= 3.9. + openbsd[1-2].* | openbsd3.[0-8] | openbsd3.[0-8].*) + gl_cv_func_snprintf_truncation_c99="guessing no";; + openbsd*) gl_cv_func_snprintf_truncation_c99="guessing yes";; + # Guess yes on Solaris >= 2.6. + solaris2.[0-5]*) gl_cv_func_snprintf_truncation_c99="guessing no";; + solaris*) gl_cv_func_snprintf_truncation_c99="guessing yes";; + # Guess yes on AIX >= 4. + aix[1-3]*) gl_cv_func_snprintf_truncation_c99="guessing no";; + aix*) gl_cv_func_snprintf_truncation_c99="guessing yes";; + # Guess yes on HP-UX >= 11. + hpux[7-9]* | hpux10*) gl_cv_func_snprintf_truncation_c99="guessing no";; + hpux*) gl_cv_func_snprintf_truncation_c99="guessing yes";; + # Guess yes on IRIX >= 6.5. + irix6.5) gl_cv_func_snprintf_truncation_c99="guessing yes";; + # Guess yes on OSF/1 >= 5. + osf[3-4]*) gl_cv_func_snprintf_truncation_c99="guessing no";; + osf*) gl_cv_func_snprintf_truncation_c99="guessing yes";; + # Guess yes on NetBSD >= 3. + netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*) + gl_cv_func_snprintf_truncation_c99="guessing no";; + netbsd*) gl_cv_func_snprintf_truncation_c99="guessing yes";; + # Guess yes on BeOS. + beos*) gl_cv_func_snprintf_truncation_c99="guessing yes";; + # If we don't know, assume the worst. + *) gl_cv_func_snprintf_truncation_c99="guessing no";; + esac +changequote([,])dnl + ]) + ]) +]) + +dnl Test whether the return value of the snprintf function is the number +dnl of bytes (excluding the terminating NUL) that would have been produced +dnl if the buffer had been large enough. (ISO C99, POSIX:2001) +dnl For example, this test program fails on IRIX 6.5: +dnl --------------------------------------------------------------------- +dnl #include +dnl int main() +dnl { +dnl static char buf[8]; +dnl int retval = snprintf (buf, 3, "%d", 12345); +dnl return retval >= 0 && retval < 3; +dnl } +dnl --------------------------------------------------------------------- +dnl Result is gl_cv_func_snprintf_retval_c99. + +AC_DEFUN([gl_SNPRINTF_RETVAL_C99], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether snprintf returns a byte count as in C99], + [gl_cv_func_snprintf_retval_c99], + [ + AC_TRY_RUN([ +#include +#include +static char buf[100]; +int main () +{ + strcpy (buf, "ABCDEF"); + if (snprintf (buf, 3, "%d %d", 4567, 89) != 7) + return 1; + return 0; +}], [gl_cv_func_snprintf_retval_c99=yes], [gl_cv_func_snprintf_retval_c99=no], + [ +changequote(,)dnl + case "$host_os" in + # Guess yes on glibc systems. + *-gnu*) gl_cv_func_snprintf_retval_c99="guessing yes";; + # Guess yes on FreeBSD >= 5. + freebsd[1-4]*) gl_cv_func_snprintf_retval_c99="guessing no";; + freebsd* | kfreebsd*) gl_cv_func_snprintf_retval_c99="guessing yes";; + # Guess yes on MacOS X >= 10.3. + darwin[1-6].*) gl_cv_func_snprintf_retval_c99="guessing no";; + darwin*) gl_cv_func_snprintf_retval_c99="guessing yes";; + # Guess yes on OpenBSD >= 3.9. + openbsd[1-2].* | openbsd3.[0-8] | openbsd3.[0-8].*) + gl_cv_func_snprintf_retval_c99="guessing no";; + openbsd*) gl_cv_func_snprintf_retval_c99="guessing yes";; + # Guess yes on Solaris >= 2.6. + solaris2.[0-5]*) gl_cv_func_snprintf_retval_c99="guessing no";; + solaris*) gl_cv_func_snprintf_retval_c99="guessing yes";; + # Guess yes on AIX >= 4. + aix[1-3]*) gl_cv_func_snprintf_retval_c99="guessing no";; + aix*) gl_cv_func_snprintf_retval_c99="guessing yes";; + # Guess yes on NetBSD >= 3. + netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*) + gl_cv_func_snprintf_retval_c99="guessing no";; + netbsd*) gl_cv_func_snprintf_retval_c99="guessing yes";; + # Guess yes on BeOS. + beos*) gl_cv_func_snprintf_retval_c99="guessing yes";; + # If we don't know, assume the worst. + *) gl_cv_func_snprintf_retval_c99="guessing no";; + esac +changequote([,])dnl + ]) + ]) +]) + +dnl Test whether the snprintf function supports the %n format directive +dnl also in truncated portions of the format string. (ISO C99, POSIX:2001) +dnl Result is gl_cv_func_snprintf_directive_n. + +AC_DEFUN([gl_SNPRINTF_DIRECTIVE_N], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether snprintf fully supports the 'n' directive], + [gl_cv_func_snprintf_directive_n], + [ + AC_TRY_RUN([ +#include +#include +static char fmtstring[10]; +static char buf[100]; +int main () +{ + int count = -1; + /* Copy the format string. Some systems (glibc with _FORTIFY_SOURCE=2) + support %n in format strings in read-only memory but not in writable + memory. */ + strcpy (fmtstring, "%d %n"); + snprintf (buf, 4, fmtstring, 12345, &count, 33, 44, 55); + if (count != 6) + return 1; + return 0; +}], [gl_cv_func_snprintf_directive_n=yes], [gl_cv_func_snprintf_directive_n=no], + [ +changequote(,)dnl + case "$host_os" in + # Guess yes on glibc systems. + *-gnu*) gl_cv_func_snprintf_directive_n="guessing yes";; + # Guess yes on FreeBSD >= 5. + freebsd[1-4]*) gl_cv_func_snprintf_directive_n="guessing no";; + freebsd* | kfreebsd*) gl_cv_func_snprintf_directive_n="guessing yes";; + # Guess yes on MacOS X >= 10.3. + darwin[1-6].*) gl_cv_func_snprintf_directive_n="guessing no";; + darwin*) gl_cv_func_snprintf_directive_n="guessing yes";; + # Guess yes on Solaris >= 2.6. + solaris2.[0-5]*) gl_cv_func_snprintf_directive_n="guessing no";; + solaris*) gl_cv_func_snprintf_directive_n="guessing yes";; + # Guess yes on AIX >= 4. + aix[1-3]*) gl_cv_func_snprintf_directive_n="guessing no";; + aix*) gl_cv_func_snprintf_directive_n="guessing yes";; + # Guess yes on IRIX >= 6.5. + irix6.5) gl_cv_func_snprintf_directive_n="guessing yes";; + # Guess yes on OSF/1 >= 5. + osf[3-4]*) gl_cv_func_snprintf_directive_n="guessing no";; + osf*) gl_cv_func_snprintf_directive_n="guessing yes";; + # Guess yes on NetBSD >= 3. + netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*) + gl_cv_func_snprintf_directive_n="guessing no";; + netbsd*) gl_cv_func_snprintf_directive_n="guessing yes";; + # Guess yes on BeOS. + beos*) gl_cv_func_snprintf_directive_n="guessing yes";; + # If we don't know, assume the worst. + *) gl_cv_func_snprintf_directive_n="guessing no";; + esac +changequote([,])dnl + ]) + ]) +]) + +dnl Test whether the snprintf function, when passed a size = 1, writes any +dnl output without bounds in this case, behaving like sprintf. This is the +dnl case on Linux libc5. +dnl Result is gl_cv_func_snprintf_size1. + +AC_DEFUN([gl_SNPRINTF_SIZE1], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_CACHE_CHECK([whether snprintf respects a size of 1], + [gl_cv_func_snprintf_size1], + [ + AC_TRY_RUN([ +#include +int main() +{ + static char buf[8] = { 'D', 'E', 'A', 'D', 'B', 'E', 'E', 'F' }; + snprintf (buf, 1, "%d", 12345); + return buf[1] != 'E'; +}], + [gl_cv_func_snprintf_size1=yes], + [gl_cv_func_snprintf_size1=no], + [gl_cv_func_snprintf_size1="guessing yes"]) + ]) +]) + +dnl Test whether the vsnprintf function, when passed a zero size, produces no +dnl output. (ISO C99, POSIX:2001) +dnl For example, snprintf nevertheless writes a NUL byte in this case +dnl on OSF/1 5.1: +dnl --------------------------------------------------------------------- +dnl #include +dnl int main() +dnl { +dnl static char buf[8] = { 'D', 'E', 'A', 'D', 'B', 'E', 'E', 'F' }; +dnl snprintf (buf, 0, "%d", 12345); +dnl return buf[0] != 'D'; +dnl } +dnl --------------------------------------------------------------------- +dnl And vsnprintf writes any output without bounds in this case, behaving like +dnl vsprintf, on HP-UX 11 and OSF/1 5.1: +dnl --------------------------------------------------------------------- +dnl #include +dnl #include +dnl static int my_snprintf (char *buf, int size, const char *format, ...) +dnl { +dnl va_list args; +dnl int ret; +dnl va_start (args, format); +dnl ret = vsnprintf (buf, size, format, args); +dnl va_end (args); +dnl return ret; +dnl } +dnl int main() +dnl { +dnl static char buf[8] = { 'D', 'E', 'A', 'D', 'B', 'E', 'E', 'F' }; +dnl my_snprintf (buf, 0, "%d", 12345); +dnl return buf[0] != 'D'; +dnl } +dnl --------------------------------------------------------------------- +dnl Result is gl_cv_func_vsnprintf_zerosize_c99. + +AC_DEFUN([gl_VSNPRINTF_ZEROSIZE_C99], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether vsnprintf respects a zero size as in C99], + [gl_cv_func_vsnprintf_zerosize_c99], + [ + AC_TRY_RUN([ +#include +#include +static int my_snprintf (char *buf, int size, const char *format, ...) +{ + va_list args; + int ret; + va_start (args, format); + ret = vsnprintf (buf, size, format, args); + va_end (args); + return ret; +} +int main() +{ + static char buf[8] = { 'D', 'E', 'A', 'D', 'B', 'E', 'E', 'F' }; + my_snprintf (buf, 0, "%d", 12345); + return buf[0] != 'D'; +}], + [gl_cv_func_vsnprintf_zerosize_c99=yes], + [gl_cv_func_vsnprintf_zerosize_c99=no], + [ +changequote(,)dnl + case "$host_os" in + # Guess yes on glibc systems. + *-gnu*) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";; + # Guess yes on FreeBSD >= 5. + freebsd[1-4]*) gl_cv_func_vsnprintf_zerosize_c99="guessing no";; + freebsd* | kfreebsd*) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";; + # Guess yes on MacOS X >= 10.3. + darwin[1-6].*) gl_cv_func_vsnprintf_zerosize_c99="guessing no";; + darwin*) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";; + # Guess yes on Cygwin. + cygwin*) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";; + # Guess yes on Solaris >= 2.6. + solaris2.[0-5]*) gl_cv_func_vsnprintf_zerosize_c99="guessing no";; + solaris*) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";; + # Guess yes on AIX >= 4. + aix[1-3]*) gl_cv_func_vsnprintf_zerosize_c99="guessing no";; + aix*) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";; + # Guess yes on IRIX >= 6.5. + irix6.5) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";; + # Guess yes on NetBSD >= 3. + netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*) + gl_cv_func_vsnprintf_zerosize_c99="guessing no";; + netbsd*) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";; + # Guess yes on BeOS. + beos*) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";; + # Guess yes on mingw. + mingw* | pw*) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";; + # If we don't know, assume the worst. + *) gl_cv_func_vsnprintf_zerosize_c99="guessing no";; + esac +changequote([,])dnl + ]) + ]) +]) + +dnl The results of these tests on various platforms are: +dnl +dnl 1 = gl_PRINTF_SIZES_C99 +dnl 2 = gl_PRINTF_LONG_DOUBLE +dnl 3 = gl_PRINTF_INFINITE +dnl 4 = gl_PRINTF_INFINITE_LONG_DOUBLE +dnl 5 = gl_PRINTF_DIRECTIVE_A +dnl 6 = gl_PRINTF_DIRECTIVE_F +dnl 7 = gl_PRINTF_DIRECTIVE_N +dnl 8 = gl_PRINTF_DIRECTIVE_LS +dnl 9 = gl_PRINTF_POSITIONS +dnl 10 = gl_PRINTF_FLAG_GROUPING +dnl 11 = gl_PRINTF_FLAG_LEFTADJUST +dnl 12 = gl_PRINTF_FLAG_ZERO +dnl 13 = gl_PRINTF_PRECISION +dnl 14 = gl_PRINTF_ENOMEM +dnl 15 = gl_SNPRINTF_PRESENCE +dnl 16 = gl_SNPRINTF_TRUNCATION_C99 +dnl 17 = gl_SNPRINTF_RETVAL_C99 +dnl 18 = gl_SNPRINTF_DIRECTIVE_N +dnl 19 = gl_SNPRINTF_SIZE1 +dnl 20 = gl_VSNPRINTF_ZEROSIZE_C99 +dnl +dnl 1 = checking whether printf supports size specifiers as in C99... +dnl 2 = checking whether printf supports 'long double' arguments... +dnl 3 = checking whether printf supports infinite 'double' arguments... +dnl 4 = checking whether printf supports infinite 'long double' arguments... +dnl 5 = checking whether printf supports the 'a' and 'A' directives... +dnl 6 = checking whether printf supports the 'F' directive... +dnl 7 = checking whether printf supports the 'n' directive... +dnl 8 = checking whether printf supports the 'ls' directive... +dnl 9 = checking whether printf supports POSIX/XSI format strings with positions... +dnl 10 = checking whether printf supports the grouping flag... +dnl 11 = checking whether printf supports the left-adjust flag correctly... +dnl 12 = checking whether printf supports the zero flag correctly... +dnl 13 = checking whether printf supports large precisions... +dnl 14 = checking whether printf survives out-of-memory conditions... +dnl 15 = checking for snprintf... +dnl 16 = checking whether snprintf truncates the result as in C99... +dnl 17 = checking whether snprintf returns a byte count as in C99... +dnl 18 = checking whether snprintf fully supports the 'n' directive... +dnl 19 = checking whether snprintf respects a size of 1... +dnl 20 = checking whether vsnprintf respects a zero size as in C99... +dnl +dnl . = yes, # = no. +dnl +dnl 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 +dnl glibc 2.5 . . . . . . . . . . . . . . . . . . . . +dnl glibc 2.3.6 . . . . # . . . . . . . . . . . . . . . +dnl FreeBSD 5.4, 6.1 . . . . # . . . . . . # . # . . . . . . +dnl MacOS X 10.3.9 . . . . # . . . . . . # . # . . . . . . +dnl OpenBSD 3.9, 4.0 . . # # # # . # . # . # . # . . . . . . +dnl Cygwin 1.7.0 (2009) . . . # . . . ? . . . . . ? . . . . . . +dnl Cygwin 1.5.25 (2008) . . . # # . . # . . . . . # . . . . . . +dnl Cygwin 1.5.19 (2006) # . . # # # . # . # . # # # . . . . . . +dnl Solaris 10 . . # # # . . # . . . # . . . . . . . . +dnl Solaris 2.6 ... 9 # . # # # # . # . . . # . . . . . . . . +dnl Solaris 2.5.1 # . # # # # . # . . . # . . # # # # # # +dnl AIX 5.2 . . # # # . . . . . . # . . . . . . . . +dnl AIX 4.3.2, 5.1 # . # # # # . . . . . # . . . . . . . . +dnl HP-UX 11.31 . . . . # . . . . . . # . . . . # # . . +dnl HP-UX 11.{00,11,23} # . . . # # . . . . . # . . . . # # . # +dnl HP-UX 10.20 # . # . # # . ? . . # # . . . . # # ? # +dnl IRIX 6.5 # . # # # # . # . . . # . . . . # . . . +dnl OSF/1 5.1 # . # # # # . . . . . # . . . . # . . # +dnl OSF/1 4.0d # . # # # # . . . . . # . . # # # # # # +dnl NetBSD 4.0 . ? ? ? ? ? . ? . ? ? ? ? ? . . . ? ? ? +dnl NetBSD 3.0 . . . . # # . ? # # ? # . # . . . . . . +dnl Haiku . . . # # # . # . . . . . ? . . . . . . +dnl BeOS # # . # # # . ? # . ? . # ? . . . . . . +dnl mingw # # # # # # . . # # . # # ? . # # # . . diff --git a/m4/putenv.m4 b/m4/putenv.m4 new file mode 100644 index 000000000..120f5a4a5 --- /dev/null +++ b/m4/putenv.m4 @@ -0,0 +1,41 @@ +# putenv.m4 serial 16 +dnl Copyright (C) 2002-2009 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Jim Meyering. +dnl +dnl Check whether putenv ("FOO") removes FOO from the environment. +dnl The putenv in libc on at least SunOS 4.1.4 does *not* do that. + +AC_DEFUN([gl_FUNC_PUTENV], +[ + AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) + AC_CACHE_CHECK([for putenv compatible with GNU and SVID], + [gl_cv_func_svid_putenv], + [AC_RUN_IFELSE([AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT],[[ + /* Put it in env. */ + if (putenv ("CONFTEST_putenv=val")) + return 1; + + /* Try to remove it. */ + if (putenv ("CONFTEST_putenv")) + return 1; + + /* Make sure it was deleted. */ + if (getenv ("CONFTEST_putenv") != 0) + return 1; + + return 0; + ]])], + gl_cv_func_svid_putenv=yes, + gl_cv_func_svid_putenv=no, + dnl When crosscompiling, assume putenv is broken. + gl_cv_func_svid_putenv=no) + ]) + if test $gl_cv_func_svid_putenv = no; then + REPLACE_PUTENV=1 + AC_LIBOBJ([putenv]) + fi +]) diff --git a/m4/readlink.m4 b/m4/readlink.m4 new file mode 100644 index 000000000..ff3f1f587 --- /dev/null +++ b/m4/readlink.m4 @@ -0,0 +1,29 @@ +# readlink.m4 serial 5 +dnl Copyright (C) 2003, 2007, 2009 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_READLINK], +[ + AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) + AC_CHECK_FUNCS_ONCE([readlink]) + if test $ac_cv_func_readlink = no; then + HAVE_READLINK=0 + AC_LIBOBJ([readlink]) + gl_PREREQ_READLINK + fi +]) + +# Like gl_FUNC_READLINK, except prepare for separate compilation (no AC_LIBOBJ). +AC_DEFUN([gl_FUNC_READLINK_SEPARATE], +[ + AC_CHECK_FUNCS_ONCE([readlink]) + gl_PREREQ_READLINK +]) + +# Prerequisites of lib/readlink.c. +AC_DEFUN([gl_PREREQ_READLINK], +[ + : +]) diff --git a/m4/size_max.m4 b/m4/size_max.m4 new file mode 100644 index 000000000..35bd3d6ae --- /dev/null +++ b/m4/size_max.m4 @@ -0,0 +1,75 @@ +# size_max.m4 serial 9 +dnl Copyright (C) 2003, 2005-2006, 2008-2009 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. + +AC_DEFUN([gl_SIZE_MAX], +[ + AC_CHECK_HEADERS([stdint.h]) + dnl First test whether the system already has SIZE_MAX. + AC_CACHE_CHECK([for SIZE_MAX], [gl_cv_size_max], [ + gl_cv_size_max= + AC_EGREP_CPP([Found it], [ +#include +#if HAVE_STDINT_H +#include +#endif +#ifdef SIZE_MAX +Found it +#endif +], [gl_cv_size_max=yes]) + if test -z "$gl_cv_size_max"; then + dnl Define it ourselves. Here we assume that the type 'size_t' is not wider + dnl than the type 'unsigned long'. Try hard to find a definition that can + dnl be used in a preprocessor #if, i.e. doesn't contain a cast. + AC_COMPUTE_INT([size_t_bits_minus_1], [sizeof (size_t) * CHAR_BIT - 1], + [#include +#include ], [size_t_bits_minus_1=]) + AC_COMPUTE_INT([fits_in_uint], [sizeof (size_t) <= sizeof (unsigned int)], + [#include ], [fits_in_uint=]) + if test -n "$size_t_bits_minus_1" && test -n "$fits_in_uint"; then + if test $fits_in_uint = 1; then + dnl Even though SIZE_MAX fits in an unsigned int, it must be of type + dnl 'unsigned long' if the type 'size_t' is the same as 'unsigned long'. + AC_TRY_COMPILE([#include + extern size_t foo; + extern unsigned long foo; + ], [], [fits_in_uint=0]) + fi + dnl We cannot use 'expr' to simplify this expression, because 'expr' + dnl works only with 'long' integers in the host environment, while we + dnl might be cross-compiling from a 32-bit platform to a 64-bit platform. + if test $fits_in_uint = 1; then + gl_cv_size_max="(((1U << $size_t_bits_minus_1) - 1) * 2 + 1)" + else + gl_cv_size_max="(((1UL << $size_t_bits_minus_1) - 1) * 2 + 1)" + fi + else + dnl Shouldn't happen, but who knows... + gl_cv_size_max='((size_t)~(size_t)0)' + fi + fi + ]) + if test "$gl_cv_size_max" != yes; then + AC_DEFINE_UNQUOTED([SIZE_MAX], [$gl_cv_size_max], + [Define as the maximum value of type 'size_t', if the system doesn't define it.]) + fi + dnl Don't redefine SIZE_MAX in config.h if config.h is re-included after + dnl . Remember that the #undef in AH_VERBATIM gets replaced with + dnl #define by AC_DEFINE_UNQUOTED. + AH_VERBATIM([SIZE_MAX], +[/* Define as the maximum value of type 'size_t', if the system doesn't define + it. */ +#ifndef SIZE_MAX +# undef SIZE_MAX +#endif]) +]) + +dnl Autoconf >= 2.61 has AC_COMPUTE_INT built-in. +dnl Remove this when we can assume autoconf >= 2.61. +m4_ifdef([AC_COMPUTE_INT], [], [ + AC_DEFUN([AC_COMPUTE_INT], [_AC_COMPUTE_INT([$2],[$1],[$3],[$4])]) +]) diff --git a/m4/stdbool.m4 b/m4/stdbool.m4 index 2204ecd98..57c804a80 100644 --- a/m4/stdbool.m4 +++ b/m4/stdbool.m4 @@ -1,6 +1,6 @@ # Check for stdbool.h that conforms to C99. -dnl Copyright (C) 2002-2006 Free Software Foundation, Inc. +dnl Copyright (C) 2002-2006, 2009 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. @@ -111,5 +111,5 @@ AC_DEFUN([AC_HEADER_STDBOOL], [ac_cv_header_stdbool_h=no])]) AC_CHECK_TYPES([_Bool]) if test $ac_cv_header_stdbool_h = yes; then - AC_DEFINE(HAVE_STDBOOL_H, 1, [Define to 1 if stdbool.h conforms to C99.]) + AC_DEFINE([HAVE_STDBOOL_H], [1], [Define to 1 if stdbool.h conforms to C99.]) fi]) diff --git a/m4/stdint.m4 b/m4/stdint.m4 new file mode 100644 index 000000000..a2e8bdd62 --- /dev/null +++ b/m4/stdint.m4 @@ -0,0 +1,472 @@ +# stdint.m4 serial 34 +dnl Copyright (C) 2001-2009 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Paul Eggert and Bruno Haible. +dnl Test whether is supported or must be substituted. + +AC_DEFUN([gl_STDINT_H], +[ + AC_PREREQ([2.59])dnl + + dnl Check for long long int and unsigned long long int. + AC_REQUIRE([AC_TYPE_LONG_LONG_INT]) + if test $ac_cv_type_long_long_int = yes; then + HAVE_LONG_LONG_INT=1 + else + HAVE_LONG_LONG_INT=0 + fi + AC_SUBST([HAVE_LONG_LONG_INT]) + AC_REQUIRE([AC_TYPE_UNSIGNED_LONG_LONG_INT]) + if test $ac_cv_type_unsigned_long_long_int = yes; then + HAVE_UNSIGNED_LONG_LONG_INT=1 + else + HAVE_UNSIGNED_LONG_LONG_INT=0 + fi + AC_SUBST([HAVE_UNSIGNED_LONG_LONG_INT]) + + dnl Check for . + dnl AC_INCLUDES_DEFAULT defines $ac_cv_header_inttypes_h. + if test $ac_cv_header_inttypes_h = yes; then + HAVE_INTTYPES_H=1 + else + HAVE_INTTYPES_H=0 + fi + AC_SUBST([HAVE_INTTYPES_H]) + + dnl Check for . + dnl AC_INCLUDES_DEFAULT defines $ac_cv_header_sys_types_h. + if test $ac_cv_header_sys_types_h = yes; then + HAVE_SYS_TYPES_H=1 + else + HAVE_SYS_TYPES_H=0 + fi + AC_SUBST([HAVE_SYS_TYPES_H]) + + gl_CHECK_NEXT_HEADERS([stdint.h]) + if test $ac_cv_header_stdint_h = yes; then + HAVE_STDINT_H=1 + else + HAVE_STDINT_H=0 + fi + AC_SUBST([HAVE_STDINT_H]) + + dnl Now see whether we need a substitute . + if test $ac_cv_header_stdint_h = yes; then + AC_CACHE_CHECK([whether stdint.h conforms to C99], + [gl_cv_header_working_stdint_h], + [gl_cv_header_working_stdint_h=no + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ +#define __STDC_LIMIT_MACROS 1 /* to make it work also in C++ mode */ +#define __STDC_CONSTANT_MACROS 1 /* to make it work also in C++ mode */ +#define _GL_JUST_INCLUDE_SYSTEM_STDINT_H 1 /* work if build isn't clean */ +#include +/* Dragonfly defines WCHAR_MIN, WCHAR_MAX only in . */ +#if !(defined WCHAR_MIN && defined WCHAR_MAX) +#error "WCHAR_MIN, WCHAR_MAX not defined in " +#endif +] +gl_STDINT_INCLUDES +[ +#ifdef INT8_MAX +int8_t a1 = INT8_MAX; +int8_t a1min = INT8_MIN; +#endif +#ifdef INT16_MAX +int16_t a2 = INT16_MAX; +int16_t a2min = INT16_MIN; +#endif +#ifdef INT32_MAX +int32_t a3 = INT32_MAX; +int32_t a3min = INT32_MIN; +#endif +#ifdef INT64_MAX +int64_t a4 = INT64_MAX; +int64_t a4min = INT64_MIN; +#endif +#ifdef UINT8_MAX +uint8_t b1 = UINT8_MAX; +#else +typedef int b1[(unsigned char) -1 != 255 ? 1 : -1]; +#endif +#ifdef UINT16_MAX +uint16_t b2 = UINT16_MAX; +#endif +#ifdef UINT32_MAX +uint32_t b3 = UINT32_MAX; +#endif +#ifdef UINT64_MAX +uint64_t b4 = UINT64_MAX; +#endif +int_least8_t c1 = INT8_C (0x7f); +int_least8_t c1max = INT_LEAST8_MAX; +int_least8_t c1min = INT_LEAST8_MIN; +int_least16_t c2 = INT16_C (0x7fff); +int_least16_t c2max = INT_LEAST16_MAX; +int_least16_t c2min = INT_LEAST16_MIN; +int_least32_t c3 = INT32_C (0x7fffffff); +int_least32_t c3max = INT_LEAST32_MAX; +int_least32_t c3min = INT_LEAST32_MIN; +int_least64_t c4 = INT64_C (0x7fffffffffffffff); +int_least64_t c4max = INT_LEAST64_MAX; +int_least64_t c4min = INT_LEAST64_MIN; +uint_least8_t d1 = UINT8_C (0xff); +uint_least8_t d1max = UINT_LEAST8_MAX; +uint_least16_t d2 = UINT16_C (0xffff); +uint_least16_t d2max = UINT_LEAST16_MAX; +uint_least32_t d3 = UINT32_C (0xffffffff); +uint_least32_t d3max = UINT_LEAST32_MAX; +uint_least64_t d4 = UINT64_C (0xffffffffffffffff); +uint_least64_t d4max = UINT_LEAST64_MAX; +int_fast8_t e1 = INT_FAST8_MAX; +int_fast8_t e1min = INT_FAST8_MIN; +int_fast16_t e2 = INT_FAST16_MAX; +int_fast16_t e2min = INT_FAST16_MIN; +int_fast32_t e3 = INT_FAST32_MAX; +int_fast32_t e3min = INT_FAST32_MIN; +int_fast64_t e4 = INT_FAST64_MAX; +int_fast64_t e4min = INT_FAST64_MIN; +uint_fast8_t f1 = UINT_FAST8_MAX; +uint_fast16_t f2 = UINT_FAST16_MAX; +uint_fast32_t f3 = UINT_FAST32_MAX; +uint_fast64_t f4 = UINT_FAST64_MAX; +#ifdef INTPTR_MAX +intptr_t g = INTPTR_MAX; +intptr_t gmin = INTPTR_MIN; +#endif +#ifdef UINTPTR_MAX +uintptr_t h = UINTPTR_MAX; +#endif +intmax_t i = INTMAX_MAX; +uintmax_t j = UINTMAX_MAX; + +#include /* for CHAR_BIT */ +#define TYPE_MINIMUM(t) \ + ((t) ((t) 0 < (t) -1 ? (t) 0 : ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1))) +#define TYPE_MAXIMUM(t) \ + ((t) ((t) 0 < (t) -1 ? (t) -1 : ~ (~ (t) 0 << (sizeof (t) * CHAR_BIT - 1)))) +struct s { + int check_PTRDIFF: + PTRDIFF_MIN == TYPE_MINIMUM (ptrdiff_t) + && PTRDIFF_MAX == TYPE_MAXIMUM (ptrdiff_t) + ? 1 : -1; + /* Detect bug in FreeBSD 6.0 / ia64. */ + int check_SIG_ATOMIC: + SIG_ATOMIC_MIN == TYPE_MINIMUM (sig_atomic_t) + && SIG_ATOMIC_MAX == TYPE_MAXIMUM (sig_atomic_t) + ? 1 : -1; + int check_SIZE: SIZE_MAX == TYPE_MAXIMUM (size_t) ? 1 : -1; + int check_WCHAR: + WCHAR_MIN == TYPE_MINIMUM (wchar_t) + && WCHAR_MAX == TYPE_MAXIMUM (wchar_t) + ? 1 : -1; + /* Detect bug in mingw. */ + int check_WINT: + WINT_MIN == TYPE_MINIMUM (wint_t) + && WINT_MAX == TYPE_MAXIMUM (wint_t) + ? 1 : -1; + + /* Detect bugs in glibc 2.4 and Solaris 10 stdint.h, among others. */ + int check_UINT8_C: + (-1 < UINT8_C (0)) == (-1 < (uint_least8_t) 0) ? 1 : -1; + int check_UINT16_C: + (-1 < UINT16_C (0)) == (-1 < (uint_least16_t) 0) ? 1 : -1; + + /* Detect bugs in OpenBSD 3.9 stdint.h. */ +#ifdef UINT8_MAX + int check_uint8: (uint8_t) -1 == UINT8_MAX ? 1 : -1; +#endif +#ifdef UINT16_MAX + int check_uint16: (uint16_t) -1 == UINT16_MAX ? 1 : -1; +#endif +#ifdef UINT32_MAX + int check_uint32: (uint32_t) -1 == UINT32_MAX ? 1 : -1; +#endif +#ifdef UINT64_MAX + int check_uint64: (uint64_t) -1 == UINT64_MAX ? 1 : -1; +#endif + int check_uint_least8: (uint_least8_t) -1 == UINT_LEAST8_MAX ? 1 : -1; + int check_uint_least16: (uint_least16_t) -1 == UINT_LEAST16_MAX ? 1 : -1; + int check_uint_least32: (uint_least32_t) -1 == UINT_LEAST32_MAX ? 1 : -1; + int check_uint_least64: (uint_least64_t) -1 == UINT_LEAST64_MAX ? 1 : -1; + int check_uint_fast8: (uint_fast8_t) -1 == UINT_FAST8_MAX ? 1 : -1; + int check_uint_fast16: (uint_fast16_t) -1 == UINT_FAST16_MAX ? 1 : -1; + int check_uint_fast32: (uint_fast32_t) -1 == UINT_FAST32_MAX ? 1 : -1; + int check_uint_fast64: (uint_fast64_t) -1 == UINT_FAST64_MAX ? 1 : -1; + int check_uintptr: (uintptr_t) -1 == UINTPTR_MAX ? 1 : -1; + int check_uintmax: (uintmax_t) -1 == UINTMAX_MAX ? 1 : -1; + int check_size: (size_t) -1 == SIZE_MAX ? 1 : -1; +}; + ]])], + [dnl Determine whether the various *_MIN, *_MAX macros are usable + dnl in preprocessor expression. We could do it by compiling a test + dnl program for each of these macros. It is faster to run a program + dnl that inspects the macro expansion. + dnl This detects a bug on HP-UX 11.23/ia64. + AC_RUN_IFELSE([ + AC_LANG_PROGRAM([[ +#define __STDC_LIMIT_MACROS 1 /* to make it work also in C++ mode */ +#define __STDC_CONSTANT_MACROS 1 /* to make it work also in C++ mode */ +#define _GL_JUST_INCLUDE_SYSTEM_STDINT_H 1 /* work if build isn't clean */ +#include +] +gl_STDINT_INCLUDES +[ +#include +#include +#define MVAL(macro) MVAL1(macro) +#define MVAL1(expression) #expression +static const char *macro_values[] = + { +#ifdef INT8_MAX + MVAL (INT8_MAX), +#endif +#ifdef INT16_MAX + MVAL (INT16_MAX), +#endif +#ifdef INT32_MAX + MVAL (INT32_MAX), +#endif +#ifdef INT64_MAX + MVAL (INT64_MAX), +#endif +#ifdef UINT8_MAX + MVAL (UINT8_MAX), +#endif +#ifdef UINT16_MAX + MVAL (UINT16_MAX), +#endif +#ifdef UINT32_MAX + MVAL (UINT32_MAX), +#endif +#ifdef UINT64_MAX + MVAL (UINT64_MAX), +#endif + NULL + }; +]], [[ + const char **mv; + for (mv = macro_values; *mv != NULL; mv++) + { + const char *value = *mv; + /* Test whether it looks like a cast expression. */ + if (strncmp (value, "((unsigned int)"/*)*/, 15) == 0 + || strncmp (value, "((unsigned short)"/*)*/, 17) == 0 + || strncmp (value, "((unsigned char)"/*)*/, 16) == 0 + || strncmp (value, "((int)"/*)*/, 6) == 0 + || strncmp (value, "((signed short)"/*)*/, 15) == 0 + || strncmp (value, "((signed char)"/*)*/, 14) == 0) + return 1; + } + return 0; +]])], + [gl_cv_header_working_stdint_h=yes], + [], + [dnl When cross-compiling, assume it works. + gl_cv_header_working_stdint_h=yes + ]) + ]) + ]) + fi + if test "$gl_cv_header_working_stdint_h" = yes; then + STDINT_H= + else + dnl Check for , and for + dnl (used in Linux libc4 >= 4.6.7 and libc5). + AC_CHECK_HEADERS([sys/inttypes.h sys/bitypes.h]) + if test $ac_cv_header_sys_inttypes_h = yes; then + HAVE_SYS_INTTYPES_H=1 + else + HAVE_SYS_INTTYPES_H=0 + fi + AC_SUBST([HAVE_SYS_INTTYPES_H]) + if test $ac_cv_header_sys_bitypes_h = yes; then + HAVE_SYS_BITYPES_H=1 + else + HAVE_SYS_BITYPES_H=0 + fi + AC_SUBST([HAVE_SYS_BITYPES_H]) + + dnl Check for (missing in Linux uClibc when built without wide + dnl character support). + AC_CHECK_HEADERS_ONCE([wchar.h]) + + gl_STDINT_TYPE_PROPERTIES + STDINT_H=stdint.h + fi + AC_SUBST([STDINT_H]) +]) + +dnl gl_STDINT_BITSIZEOF(TYPES, INCLUDES) +dnl Determine the size of each of the given types in bits. +AC_DEFUN([gl_STDINT_BITSIZEOF], +[ + dnl Use a shell loop, to avoid bloating configure, and + dnl - extra AH_TEMPLATE calls, so that autoheader knows what to put into + dnl config.h.in, + dnl - extra AC_SUBST calls, so that the right substitutions are made. + m4_foreach_w([gltype], [$1], + [AH_TEMPLATE([BITSIZEOF_]translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_]), + [Define to the number of bits in type ']gltype['.])]) + for gltype in $1 ; do + AC_CACHE_CHECK([for bit size of $gltype], [gl_cv_bitsizeof_${gltype}], + [AC_COMPUTE_INT([result], [sizeof ($gltype) * CHAR_BIT], + [$2 +#include ], [result=unknown]) + eval gl_cv_bitsizeof_${gltype}=\$result + ]) + eval result=\$gl_cv_bitsizeof_${gltype} + if test $result = unknown; then + dnl Use a nonempty default, because some compilers, such as IRIX 5 cc, + dnl do a syntax check even on unused #if conditions and give an error + dnl on valid C code like this: + dnl #if 0 + dnl # if > 32 + dnl # endif + dnl #endif + result=0 + fi + GLTYPE=`echo "$gltype" | tr 'abcdefghijklmnopqrstuvwxyz ' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_'` + AC_DEFINE_UNQUOTED([BITSIZEOF_${GLTYPE}], [$result]) + eval BITSIZEOF_${GLTYPE}=\$result + done + m4_foreach_w([gltype], [$1], + [AC_SUBST([BITSIZEOF_]translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_]))]) +]) + +dnl gl_CHECK_TYPES_SIGNED(TYPES, INCLUDES) +dnl Determine the signedness of each of the given types. +dnl Define HAVE_SIGNED_TYPE if type is signed. +AC_DEFUN([gl_CHECK_TYPES_SIGNED], +[ + dnl Use a shell loop, to avoid bloating configure, and + dnl - extra AH_TEMPLATE calls, so that autoheader knows what to put into + dnl config.h.in, + dnl - extra AC_SUBST calls, so that the right substitutions are made. + m4_foreach_w([gltype], [$1], + [AH_TEMPLATE([HAVE_SIGNED_]translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_]), + [Define to 1 if ']gltype[' is a signed integer type.])]) + for gltype in $1 ; do + AC_CACHE_CHECK([whether $gltype is signed], [gl_cv_type_${gltype}_signed], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([$2[ + int verify[2 * (($gltype) -1 < ($gltype) 0) - 1];]])], + result=yes, result=no) + eval gl_cv_type_${gltype}_signed=\$result + ]) + eval result=\$gl_cv_type_${gltype}_signed + GLTYPE=`echo $gltype | tr 'abcdefghijklmnopqrstuvwxyz ' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_'` + if test "$result" = yes; then + AC_DEFINE_UNQUOTED([HAVE_SIGNED_${GLTYPE}], [1]) + eval HAVE_SIGNED_${GLTYPE}=1 + else + eval HAVE_SIGNED_${GLTYPE}=0 + fi + done + m4_foreach_w([gltype], [$1], + [AC_SUBST([HAVE_SIGNED_]translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_]))]) +]) + +dnl gl_INTEGER_TYPE_SUFFIX(TYPES, INCLUDES) +dnl Determine the suffix to use for integer constants of the given types. +dnl Define t_SUFFIX for each such type. +AC_DEFUN([gl_INTEGER_TYPE_SUFFIX], +[ + dnl Use a shell loop, to avoid bloating configure, and + dnl - extra AH_TEMPLATE calls, so that autoheader knows what to put into + dnl config.h.in, + dnl - extra AC_SUBST calls, so that the right substitutions are made. + m4_foreach_w([gltype], [$1], + [AH_TEMPLATE(translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_])[_SUFFIX], + [Define to l, ll, u, ul, ull, etc., as suitable for + constants of type ']gltype['.])]) + for gltype in $1 ; do + AC_CACHE_CHECK([for $gltype integer literal suffix], + [gl_cv_type_${gltype}_suffix], + [eval gl_cv_type_${gltype}_suffix=no + eval result=\$gl_cv_type_${gltype}_signed + if test "$result" = yes; then + glsufu= + else + glsufu=u + fi + for glsuf in "$glsufu" ${glsufu}l ${glsufu}ll ${glsufu}i64; do + case $glsuf in + '') gltype1='int';; + l) gltype1='long int';; + ll) gltype1='long long int';; + i64) gltype1='__int64';; + u) gltype1='unsigned int';; + ul) gltype1='unsigned long int';; + ull) gltype1='unsigned long long int';; + ui64)gltype1='unsigned __int64';; + esac + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([$2[ + extern $gltype foo; + extern $gltype1 foo;]])], + [eval gl_cv_type_${gltype}_suffix=\$glsuf]) + eval result=\$gl_cv_type_${gltype}_suffix + test "$result" != no && break + done]) + GLTYPE=`echo $gltype | tr 'abcdefghijklmnopqrstuvwxyz ' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_'` + eval result=\$gl_cv_type_${gltype}_suffix + test "$result" = no && result= + eval ${GLTYPE}_SUFFIX=\$result + AC_DEFINE_UNQUOTED([${GLTYPE}_SUFFIX], [$result]) + done + m4_foreach_w([gltype], [$1], + [AC_SUBST(translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_])[_SUFFIX])]) +]) + +dnl gl_STDINT_INCLUDES +AC_DEFUN([gl_STDINT_INCLUDES], +[[ + /* BSD/OS 4.0.1 has a bug: , and must be + included before . */ + #include + #include + #if HAVE_WCHAR_H + # include + # include + # include + #endif +]]) + +dnl gl_STDINT_TYPE_PROPERTIES +dnl Compute HAVE_SIGNED_t, BITSIZEOF_t and t_SUFFIX, for all the types t +dnl of interest to stdint.in.h. +AC_DEFUN([gl_STDINT_TYPE_PROPERTIES], +[ + AC_REQUIRE([gl_MULTIARCH]) + if test $APPLE_UNIVERSAL_BUILD = 0; then + gl_STDINT_BITSIZEOF([ptrdiff_t size_t], + [gl_STDINT_INCLUDES]) + fi + gl_STDINT_BITSIZEOF([sig_atomic_t wchar_t wint_t], + [gl_STDINT_INCLUDES]) + gl_CHECK_TYPES_SIGNED([sig_atomic_t wchar_t wint_t], + [gl_STDINT_INCLUDES]) + gl_cv_type_ptrdiff_t_signed=yes + gl_cv_type_size_t_signed=no + if test $APPLE_UNIVERSAL_BUILD = 0; then + gl_INTEGER_TYPE_SUFFIX([ptrdiff_t size_t], + [gl_STDINT_INCLUDES]) + fi + gl_INTEGER_TYPE_SUFFIX([sig_atomic_t wchar_t wint_t], + [gl_STDINT_INCLUDES]) +]) + +dnl Autoconf >= 2.61 has AC_COMPUTE_INT built-in. +dnl Remove this when we can assume autoconf >= 2.61. +m4_ifdef([AC_COMPUTE_INT], [], [ + AC_DEFUN([AC_COMPUTE_INT], [_AC_COMPUTE_INT([$2],[$1],[$3],[$4])]) +]) + +# Hey Emacs! +# Local Variables: +# indent-tabs-mode: nil +# End: diff --git a/m4/stdint_h.m4 b/m4/stdint_h.m4 new file mode 100644 index 000000000..82f0c244c --- /dev/null +++ b/m4/stdint_h.m4 @@ -0,0 +1,26 @@ +# stdint_h.m4 serial 8 +dnl Copyright (C) 1997-2004, 2006, 2008, 2009 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Paul Eggert. + +# Define HAVE_STDINT_H_WITH_UINTMAX if exists, +# doesn't clash with , and declares uintmax_t. + +AC_DEFUN([gl_AC_HEADER_STDINT_H], +[ + AC_CACHE_CHECK([for stdint.h], [gl_cv_header_stdint_h], + [AC_TRY_COMPILE( + [#include +#include ], + [uintmax_t i = (uintmax_t) -1; return !i;], + [gl_cv_header_stdint_h=yes], + [gl_cv_header_stdint_h=no])]) + if test $gl_cv_header_stdint_h = yes; then + AC_DEFINE_UNQUOTED([HAVE_STDINT_H_WITH_UINTMAX], [1], + [Define if exists, doesn't clash with , + and declares uintmax_t. ]) + fi +]) diff --git a/m4/stdio_h.m4 b/m4/stdio_h.m4 new file mode 100644 index 000000000..fcbe68f6b --- /dev/null +++ b/m4/stdio_h.m4 @@ -0,0 +1,136 @@ +# stdio_h.m4 serial 16 +dnl Copyright (C) 2007-2009 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_STDIO_H], +[ + AC_REQUIRE([gl_STDIO_H_DEFAULTS]) + gl_CHECK_NEXT_HEADERS([stdio.h]) + dnl No need to create extra modules for these functions. Everyone who uses + dnl likely needs them. + GNULIB_FPRINTF=1 + GNULIB_PRINTF=1 + GNULIB_VFPRINTF=1 + GNULIB_VPRINTF=1 + GNULIB_FPUTC=1 + GNULIB_PUTC=1 + GNULIB_PUTCHAR=1 + GNULIB_FPUTS=1 + GNULIB_PUTS=1 + GNULIB_FWRITE=1 + dnl This ifdef is just an optimization, to avoid performing a configure + dnl check whose result is not used. It does not make the test of + dnl GNULIB_STDIO_H_SIGPIPE or GNULIB_SIGPIPE redundant. + m4_ifdef([gl_SIGNAL_SIGPIPE], [ + gl_SIGNAL_SIGPIPE + if test $gl_cv_header_signal_h_SIGPIPE != yes; then + REPLACE_STDIO_WRITE_FUNCS=1 + AC_LIBOBJ([stdio-write]) + fi + ]) +]) + +AC_DEFUN([gl_STDIO_MODULE_INDICATOR], +[ + dnl Use AC_REQUIRE here, so that the default settings are expanded once only. + AC_REQUIRE([gl_STDIO_H_DEFAULTS]) + GNULIB_[]m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./-],[ABCDEFGHIJKLMNOPQRSTUVWXYZ___])=1 +]) + +AC_DEFUN([gl_STDIO_H_DEFAULTS], +[ + GNULIB_FPRINTF=0; AC_SUBST([GNULIB_FPRINTF]) + GNULIB_FPRINTF_POSIX=0; AC_SUBST([GNULIB_FPRINTF_POSIX]) + GNULIB_PRINTF=0; AC_SUBST([GNULIB_PRINTF]) + GNULIB_PRINTF_POSIX=0; AC_SUBST([GNULIB_PRINTF_POSIX]) + GNULIB_SNPRINTF=0; AC_SUBST([GNULIB_SNPRINTF]) + GNULIB_SPRINTF_POSIX=0; AC_SUBST([GNULIB_SPRINTF_POSIX]) + GNULIB_VFPRINTF=0; AC_SUBST([GNULIB_VFPRINTF]) + GNULIB_VFPRINTF_POSIX=0; AC_SUBST([GNULIB_VFPRINTF_POSIX]) + GNULIB_VPRINTF=0; AC_SUBST([GNULIB_VPRINTF]) + GNULIB_VPRINTF_POSIX=0; AC_SUBST([GNULIB_VPRINTF_POSIX]) + GNULIB_VSNPRINTF=0; AC_SUBST([GNULIB_VSNPRINTF]) + GNULIB_VSPRINTF_POSIX=0; AC_SUBST([GNULIB_VSPRINTF_POSIX]) + GNULIB_DPRINTF=0; AC_SUBST([GNULIB_DPRINTF]) + GNULIB_VDPRINTF=0; AC_SUBST([GNULIB_VDPRINTF]) + GNULIB_VASPRINTF=0; AC_SUBST([GNULIB_VASPRINTF]) + GNULIB_OBSTACK_PRINTF=0; AC_SUBST([GNULIB_OBSTACK_PRINTF]) + GNULIB_OBSTACK_PRINTF_POSIX=0; AC_SUBST([GNULIB_OBSTACK_PRINTF_POSIX]) + GNULIB_FOPEN=0; AC_SUBST([GNULIB_FOPEN]) + GNULIB_FREOPEN=0; AC_SUBST([GNULIB_FREOPEN]) + GNULIB_FSEEK=0; AC_SUBST([GNULIB_FSEEK]) + GNULIB_FSEEKO=0; AC_SUBST([GNULIB_FSEEKO]) + GNULIB_FTELL=0; AC_SUBST([GNULIB_FTELL]) + GNULIB_FTELLO=0; AC_SUBST([GNULIB_FTELLO]) + GNULIB_FFLUSH=0; AC_SUBST([GNULIB_FFLUSH]) + GNULIB_FPURGE=0; AC_SUBST([GNULIB_FPURGE]) + GNULIB_FCLOSE=0; AC_SUBST([GNULIB_FCLOSE]) + GNULIB_FPUTC=0; AC_SUBST([GNULIB_FPUTC]) + GNULIB_PUTC=0; AC_SUBST([GNULIB_PUTC]) + GNULIB_PUTCHAR=0; AC_SUBST([GNULIB_PUTCHAR]) + GNULIB_FPUTS=0; AC_SUBST([GNULIB_FPUTS]) + GNULIB_PUTS=0; AC_SUBST([GNULIB_PUTS]) + GNULIB_FWRITE=0; AC_SUBST([GNULIB_FWRITE]) + GNULIB_GETDELIM=0; AC_SUBST([GNULIB_GETDELIM]) + GNULIB_GETLINE=0; AC_SUBST([GNULIB_GETLINE]) + GNULIB_PERROR=0; AC_SUBST([GNULIB_PERROR]) + GNULIB_STDIO_H_SIGPIPE=0; AC_SUBST([GNULIB_STDIO_H_SIGPIPE]) + dnl Assume proper GNU behavior unless another module says otherwise. + REPLACE_STDIO_WRITE_FUNCS=0; AC_SUBST([REPLACE_STDIO_WRITE_FUNCS]) + REPLACE_FPRINTF=0; AC_SUBST([REPLACE_FPRINTF]) + REPLACE_VFPRINTF=0; AC_SUBST([REPLACE_VFPRINTF]) + REPLACE_PRINTF=0; AC_SUBST([REPLACE_PRINTF]) + REPLACE_VPRINTF=0; AC_SUBST([REPLACE_VPRINTF]) + REPLACE_SNPRINTF=0; AC_SUBST([REPLACE_SNPRINTF]) + HAVE_DECL_SNPRINTF=1; AC_SUBST([HAVE_DECL_SNPRINTF]) + REPLACE_VSNPRINTF=0; AC_SUBST([REPLACE_VSNPRINTF]) + HAVE_DECL_VSNPRINTF=1; AC_SUBST([HAVE_DECL_VSNPRINTF]) + REPLACE_SPRINTF=0; AC_SUBST([REPLACE_SPRINTF]) + REPLACE_VSPRINTF=0; AC_SUBST([REPLACE_VSPRINTF]) + HAVE_DPRINTF=1; AC_SUBST([HAVE_DPRINTF]) + REPLACE_DPRINTF=0; AC_SUBST([REPLACE_DPRINTF]) + HAVE_VDPRINTF=1; AC_SUBST([HAVE_VDPRINTF]) + REPLACE_VDPRINTF=0; AC_SUBST([REPLACE_VDPRINTF]) + HAVE_VASPRINTF=1; AC_SUBST([HAVE_VASPRINTF]) + REPLACE_VASPRINTF=0; AC_SUBST([REPLACE_VASPRINTF]) + HAVE_DECL_OBSTACK_PRINTF=1; AC_SUBST([HAVE_DECL_OBSTACK_PRINTF]) + REPLACE_OBSTACK_PRINTF=0; AC_SUBST([REPLACE_OBSTACK_PRINTF]) + REPLACE_FOPEN=0; AC_SUBST([REPLACE_FOPEN]) + REPLACE_FREOPEN=0; AC_SUBST([REPLACE_FREOPEN]) + HAVE_FSEEKO=1; AC_SUBST([HAVE_FSEEKO]) + REPLACE_FSEEKO=0; AC_SUBST([REPLACE_FSEEKO]) + REPLACE_FSEEK=0; AC_SUBST([REPLACE_FSEEK]) + HAVE_FTELLO=1; AC_SUBST([HAVE_FTELLO]) + REPLACE_FTELLO=0; AC_SUBST([REPLACE_FTELLO]) + REPLACE_FTELL=0; AC_SUBST([REPLACE_FTELL]) + REPLACE_FFLUSH=0; AC_SUBST([REPLACE_FFLUSH]) + REPLACE_FPURGE=0; AC_SUBST([REPLACE_FPURGE]) + HAVE_DECL_FPURGE=1; AC_SUBST([HAVE_DECL_FPURGE]) + REPLACE_FCLOSE=0; AC_SUBST([REPLACE_FCLOSE]) + HAVE_DECL_GETDELIM=1; AC_SUBST([HAVE_DECL_GETDELIM]) + HAVE_DECL_GETLINE=1; AC_SUBST([HAVE_DECL_GETLINE]) + REPLACE_GETLINE=0; AC_SUBST([REPLACE_GETLINE]) + REPLACE_PERROR=0; AC_SUBST([REPLACE_PERROR]) +]) + +dnl Code shared by fseeko and ftello. Determine if large files are supported, +dnl but stdin does not start as a large file by default. +AC_DEFUN([gl_STDIN_LARGE_OFFSET], + [ + AC_CACHE_CHECK([whether stdin defaults to large file offsets], + [gl_cv_var_stdin_large_offset], + [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], +[[#if defined __SL64 && defined __SCLE /* cygwin */ + /* Cygwin 1.5.24 and earlier fail to put stdin in 64-bit mode, making + fseeko/ftello needlessly fail. This bug was fixed in 1.5.25, and + it is easier to do a version check than building a runtime test. */ +# include +# if CYGWIN_VERSION_DLL_COMBINED < CYGWIN_VERSION_DLL_MAKE_COMBINED (1005, 25) + choke me +# endif +#endif]])], + [gl_cv_var_stdin_large_offset=yes], + [gl_cv_var_stdin_large_offset=no])]) +]) diff --git a/m4/stdlib_h.m4 b/m4/stdlib_h.m4 new file mode 100644 index 000000000..b295f16b2 --- /dev/null +++ b/m4/stdlib_h.m4 @@ -0,0 +1,73 @@ +# stdlib_h.m4 serial 15 +dnl Copyright (C) 2007-2009 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_STDLIB_H], +[ + AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) + gl_CHECK_NEXT_HEADERS([stdlib.h]) + AC_CHECK_HEADERS([random.h], [], [], [AC_INCLUDES_DEFAULT]) + if test $ac_cv_header_random_h = yes; then + HAVE_RANDOM_H=1 + else + HAVE_RANDOM_H=0 + fi + AC_SUBST([HAVE_RANDOM_H]) + AC_CHECK_TYPES([struct random_data], + [], [HAVE_STRUCT_RANDOM_DATA=0], + [[#include + #if HAVE_RANDOM_H + # include + #endif + ]]) +]) + +AC_DEFUN([gl_STDLIB_MODULE_INDICATOR], +[ + dnl Use AC_REQUIRE here, so that the default settings are expanded once only. + AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) + GNULIB_[]m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./-],[ABCDEFGHIJKLMNOPQRSTUVWXYZ___])=1 +]) + +AC_DEFUN([gl_STDLIB_H_DEFAULTS], +[ + GNULIB_MALLOC_POSIX=0; AC_SUBST([GNULIB_MALLOC_POSIX]) + GNULIB_REALLOC_POSIX=0; AC_SUBST([GNULIB_REALLOC_POSIX]) + GNULIB_CALLOC_POSIX=0; AC_SUBST([GNULIB_CALLOC_POSIX]) + GNULIB_ATOLL=0; AC_SUBST([GNULIB_ATOLL]) + GNULIB_GETLOADAVG=0; AC_SUBST([GNULIB_GETLOADAVG]) + GNULIB_GETSUBOPT=0; AC_SUBST([GNULIB_GETSUBOPT]) + GNULIB_MKDTEMP=0; AC_SUBST([GNULIB_MKDTEMP]) + GNULIB_MKSTEMP=0; AC_SUBST([GNULIB_MKSTEMP]) + GNULIB_PUTENV=0; AC_SUBST([GNULIB_PUTENV]) + GNULIB_RANDOM_R=0; AC_SUBST([GNULIB_RANDOM_R]) + GNULIB_RPMATCH=0; AC_SUBST([GNULIB_RPMATCH]) + GNULIB_SETENV=0; AC_SUBST([GNULIB_SETENV]) + GNULIB_STRTOD=0; AC_SUBST([GNULIB_STRTOD]) + GNULIB_STRTOLL=0; AC_SUBST([GNULIB_STRTOLL]) + GNULIB_STRTOULL=0; AC_SUBST([GNULIB_STRTOULL]) + GNULIB_UNSETENV=0; AC_SUBST([GNULIB_UNSETENV]) + dnl Assume proper GNU behavior unless another module says otherwise. + HAVE_ATOLL=1; AC_SUBST([HAVE_ATOLL]) + HAVE_CALLOC_POSIX=1; AC_SUBST([HAVE_CALLOC_POSIX]) + HAVE_GETSUBOPT=1; AC_SUBST([HAVE_GETSUBOPT]) + HAVE_MALLOC_POSIX=1; AC_SUBST([HAVE_MALLOC_POSIX]) + HAVE_MKDTEMP=1; AC_SUBST([HAVE_MKDTEMP]) + HAVE_REALLOC_POSIX=1; AC_SUBST([HAVE_REALLOC_POSIX]) + HAVE_RANDOM_R=1; AC_SUBST([HAVE_RANDOM_R]) + HAVE_RPMATCH=1; AC_SUBST([HAVE_RPMATCH]) + HAVE_SETENV=1; AC_SUBST([HAVE_SETENV]) + HAVE_STRTOD=1; AC_SUBST([HAVE_STRTOD]) + HAVE_STRTOLL=1; AC_SUBST([HAVE_STRTOLL]) + HAVE_STRTOULL=1; AC_SUBST([HAVE_STRTOULL]) + HAVE_STRUCT_RANDOM_DATA=1; AC_SUBST([HAVE_STRUCT_RANDOM_DATA]) + HAVE_SYS_LOADAVG_H=0; AC_SUBST([HAVE_SYS_LOADAVG_H]) + HAVE_UNSETENV=1; AC_SUBST([HAVE_UNSETENV]) + HAVE_DECL_GETLOADAVG=1; AC_SUBST([HAVE_DECL_GETLOADAVG]) + REPLACE_MKSTEMP=0; AC_SUBST([REPLACE_MKSTEMP]) + REPLACE_PUTENV=0; AC_SUBST([REPLACE_PUTENV]) + REPLACE_STRTOD=0; AC_SUBST([REPLACE_STRTOD]) + VOID_UNSETENV=0; AC_SUBST([VOID_UNSETENV]) +]) diff --git a/m4/strcase.m4 b/m4/strcase.m4 index 79c525c11..0dfdb1a18 100644 --- a/m4/strcase.m4 +++ b/m4/strcase.m4 @@ -1,5 +1,5 @@ -# strcase.m4 serial 9 -dnl Copyright (C) 2002, 2005-2008 Free Software Foundation, Inc. +# strcase.m4 serial 10 +dnl Copyright (C) 2002, 2005-2009 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. @@ -13,7 +13,7 @@ AC_DEFUN([gl_STRCASE], AC_DEFUN([gl_FUNC_STRCASECMP], [ AC_REQUIRE([gl_HEADER_STRINGS_H_DEFAULTS]) - AC_REPLACE_FUNCS(strcasecmp) + AC_REPLACE_FUNCS([strcasecmp]) if test $ac_cv_func_strcasecmp = no; then HAVE_STRCASECMP=0 gl_PREREQ_STRCASECMP @@ -23,11 +23,11 @@ AC_DEFUN([gl_FUNC_STRCASECMP], AC_DEFUN([gl_FUNC_STRNCASECMP], [ AC_REQUIRE([gl_HEADER_STRINGS_H_DEFAULTS]) - AC_REPLACE_FUNCS(strncasecmp) + AC_REPLACE_FUNCS([strncasecmp]) if test $ac_cv_func_strncasecmp = no; then gl_PREREQ_STRNCASECMP fi - AC_CHECK_DECLS(strncasecmp) + AC_CHECK_DECLS([strncasecmp]) if test $ac_cv_have_decl_strncasecmp = no; then HAVE_DECL_STRNCASECMP=0 fi diff --git a/m4/strftime.m4 b/m4/strftime.m4 index 70b537894..15a87708e 100644 --- a/m4/strftime.m4 +++ b/m4/strftime.m4 @@ -1,7 +1,7 @@ -#serial 29 +# serial 32 # Copyright (C) 1996, 1997, 1999, 2000, 2001, 2002, 2003, 2004, 2005, -# 2006, 2007 Free Software Foundation, Inc. +# 2006, 2007, 2009 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -25,8 +25,8 @@ AC_DEFUN([gl_FUNC_STRFTIME], AC_REQUIRE([AC_TYPE_MBSTATE_T]) AC_REQUIRE([gl_TM_GMTOFF]) - AC_CHECK_FUNCS_ONCE(mblen mbrlen mempcpy tzset) - AC_CHECK_HEADERS_ONCE(wchar.h) + AC_CHECK_FUNCS_ONCE([tzset]) + AC_CHECK_HEADERS_ONCE([wchar.h]) AC_DEFINE([my_strftime], [nstrftime], [Define to the name of the strftime replacement function.]) diff --git a/m4/string_h.m4 b/m4/string_h.m4 new file mode 100644 index 000000000..11f09c8b8 --- /dev/null +++ b/m4/string_h.m4 @@ -0,0 +1,94 @@ +# Configure a GNU-like replacement for . + +# Copyright (C) 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. + +# serial 7 + +# Written by Paul Eggert. + +AC_DEFUN([gl_HEADER_STRING_H], +[ + dnl Use AC_REQUIRE here, so that the default behavior below is expanded + dnl once only, before all statements that occur in other macros. + AC_REQUIRE([gl_HEADER_STRING_H_BODY]) +]) + +AC_DEFUN([gl_HEADER_STRING_H_BODY], +[ + AC_REQUIRE([AC_C_RESTRICT]) + AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS]) + gl_CHECK_NEXT_HEADERS([string.h]) +]) + +AC_DEFUN([gl_STRING_MODULE_INDICATOR], +[ + dnl Use AC_REQUIRE here, so that the default settings are expanded once only. + AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS]) + GNULIB_[]m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./-],[ABCDEFGHIJKLMNOPQRSTUVWXYZ___])=1 +]) + +AC_DEFUN([gl_HEADER_STRING_H_DEFAULTS], +[ + GNULIB_MEMCHR=0; AC_SUBST([GNULIB_MEMCHR]) + GNULIB_MEMMEM=0; AC_SUBST([GNULIB_MEMMEM]) + GNULIB_MEMPCPY=0; AC_SUBST([GNULIB_MEMPCPY]) + GNULIB_MEMRCHR=0; AC_SUBST([GNULIB_MEMRCHR]) + GNULIB_RAWMEMCHR=0; AC_SUBST([GNULIB_RAWMEMCHR]) + GNULIB_STPCPY=0; AC_SUBST([GNULIB_STPCPY]) + GNULIB_STPNCPY=0; AC_SUBST([GNULIB_STPNCPY]) + GNULIB_STRCHRNUL=0; AC_SUBST([GNULIB_STRCHRNUL]) + GNULIB_STRDUP=0; AC_SUBST([GNULIB_STRDUP]) + GNULIB_STRNDUP=0; AC_SUBST([GNULIB_STRNDUP]) + GNULIB_STRNLEN=0; AC_SUBST([GNULIB_STRNLEN]) + GNULIB_STRPBRK=0; AC_SUBST([GNULIB_STRPBRK]) + GNULIB_STRSEP=0; AC_SUBST([GNULIB_STRSEP]) + GNULIB_STRSTR=0; AC_SUBST([GNULIB_STRSTR]) + GNULIB_STRCASESTR=0; AC_SUBST([GNULIB_STRCASESTR]) + GNULIB_STRTOK_R=0; AC_SUBST([GNULIB_STRTOK_R]) + GNULIB_MBSLEN=0; AC_SUBST([GNULIB_MBSLEN]) + GNULIB_MBSNLEN=0; AC_SUBST([GNULIB_MBSNLEN]) + GNULIB_MBSCHR=0; AC_SUBST([GNULIB_MBSCHR]) + GNULIB_MBSRCHR=0; AC_SUBST([GNULIB_MBSRCHR]) + GNULIB_MBSSTR=0; AC_SUBST([GNULIB_MBSSTR]) + GNULIB_MBSCASECMP=0; AC_SUBST([GNULIB_MBSCASECMP]) + GNULIB_MBSNCASECMP=0; AC_SUBST([GNULIB_MBSNCASECMP]) + GNULIB_MBSPCASECMP=0; AC_SUBST([GNULIB_MBSPCASECMP]) + GNULIB_MBSCASESTR=0; AC_SUBST([GNULIB_MBSCASESTR]) + GNULIB_MBSCSPN=0; AC_SUBST([GNULIB_MBSCSPN]) + GNULIB_MBSPBRK=0; AC_SUBST([GNULIB_MBSPBRK]) + GNULIB_MBSSPN=0; AC_SUBST([GNULIB_MBSSPN]) + GNULIB_MBSSEP=0; AC_SUBST([GNULIB_MBSSEP]) + GNULIB_MBSTOK_R=0; AC_SUBST([GNULIB_MBSTOK_R]) + GNULIB_STRERROR=0; AC_SUBST([GNULIB_STRERROR]) + GNULIB_STRSIGNAL=0; AC_SUBST([GNULIB_STRSIGNAL]) + GNULIB_STRVERSCMP=0; AC_SUBST([GNULIB_STRVERSCMP]) + dnl Assume proper GNU behavior unless another module says otherwise. + HAVE_DECL_MEMMEM=1; AC_SUBST([HAVE_DECL_MEMMEM]) + HAVE_MEMPCPY=1; AC_SUBST([HAVE_MEMPCPY]) + HAVE_DECL_MEMRCHR=1; AC_SUBST([HAVE_DECL_MEMRCHR]) + HAVE_RAWMEMCHR=1; AC_SUBST([HAVE_RAWMEMCHR]) + HAVE_STPCPY=1; AC_SUBST([HAVE_STPCPY]) + HAVE_STPNCPY=1; AC_SUBST([HAVE_STPNCPY]) + HAVE_STRCHRNUL=1; AC_SUBST([HAVE_STRCHRNUL]) + HAVE_DECL_STRDUP=1; AC_SUBST([HAVE_DECL_STRDUP]) + HAVE_STRNDUP=1; AC_SUBST([HAVE_STRNDUP]) + HAVE_DECL_STRNDUP=1; AC_SUBST([HAVE_DECL_STRNDUP]) + HAVE_DECL_STRNLEN=1; AC_SUBST([HAVE_DECL_STRNLEN]) + HAVE_STRPBRK=1; AC_SUBST([HAVE_STRPBRK]) + HAVE_STRSEP=1; AC_SUBST([HAVE_STRSEP]) + HAVE_STRCASESTR=1; AC_SUBST([HAVE_STRCASESTR]) + HAVE_DECL_STRTOK_R=1; AC_SUBST([HAVE_DECL_STRTOK_R]) + HAVE_DECL_STRERROR=1; AC_SUBST([HAVE_DECL_STRERROR]) + HAVE_DECL_STRSIGNAL=1; AC_SUBST([HAVE_DECL_STRSIGNAL]) + HAVE_STRVERSCMP=1; AC_SUBST([HAVE_STRVERSCMP]) + REPLACE_MEMCHR=0; AC_SUBST([REPLACE_MEMCHR]) + REPLACE_MEMMEM=0; AC_SUBST([REPLACE_MEMMEM]) + REPLACE_STRDUP=0; AC_SUBST([REPLACE_STRDUP]) + REPLACE_STRSTR=0; AC_SUBST([REPLACE_STRSTR]) + REPLACE_STRCASESTR=0; AC_SUBST([REPLACE_STRCASESTR]) + REPLACE_STRERROR=0; AC_SUBST([REPLACE_STRERROR]) + REPLACE_STRSIGNAL=0; AC_SUBST([REPLACE_STRSIGNAL]) +]) diff --git a/m4/sys_file_h.m4 b/m4/sys_file_h.m4 new file mode 100644 index 000000000..436c6fec1 --- /dev/null +++ b/m4/sys_file_h.m4 @@ -0,0 +1,41 @@ +# Configure a replacement for . + +# Copyright (C) 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. + +# Written by Richard W.M. Jones. + +AC_DEFUN([gl_HEADER_SYS_FILE_H], +[ + AC_REQUIRE([gl_HEADER_SYS_FILE_H_DEFAULTS]) + + dnl Only flock is defined in a working . If that + dnl function is already there, we don't want to do any substitution. + AC_CHECK_FUNCS_ONCE([flock]) + + gl_CHECK_NEXT_HEADERS([sys/file.h]) + SYS_FILE_H='sys/file.h' + AC_SUBST([SYS_FILE_H]) + + AC_CHECK_HEADERS_ONCE([sys/file.h]) + if test $ac_cv_header_sys_file_h = yes; then + HAVE_SYS_FILE_H=1 + else + HAVE_SYS_FILE_H=0 + fi + AC_SUBST([HAVE_SYS_FILE_H]) +]) + +AC_DEFUN([gl_HEADER_SYS_FILE_MODULE_INDICATOR], +[ + AC_REQUIRE([gl_HEADER_SYS_FILE_H_DEFAULTS]) + GNULIB_[]m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./-],[ABCDEFGHIJKLMNOPQRSTUVWXYZ___])=1 +]) + +AC_DEFUN([gl_HEADER_SYS_FILE_H_DEFAULTS], +[ + GNULIB_FLOCK=0; AC_SUBST([GNULIB_FLOCK]) + HAVE_FLOCK=1; AC_SUBST([HAVE_FLOCK]) +]) diff --git a/m4/time_h.m4 b/m4/time_h.m4 index d42a635ec..16fefa197 100644 --- a/m4/time_h.m4 +++ b/m4/time_h.m4 @@ -1,7 +1,6 @@ # Configure a more-standard replacement for . -# Copyright (C) 2000, 2001, 2003, 2004, 2005, 2006, 2007 Free Software -# Foundation, Inc. +# Copyright (C) 2000-2001, 2003-2007, 2009 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -30,6 +29,7 @@ AC_DEFUN([gl_HEADER_TIME_H_DEFAULTS], dnl Otherwise, replace only if someone compiles with -DGNULIB_PORTCHECK; dnl this lets maintainers check for portability. REPLACE_LOCALTIME_R=GNULIB_PORTCHECK; AC_SUBST([REPLACE_LOCALTIME_R]) + REPLACE_MKTIME=GNULIB_PORTCHECK; AC_SUBST([REPLACE_MKTIME]) REPLACE_NANOSLEEP=GNULIB_PORTCHECK; AC_SUBST([REPLACE_NANOSLEEP]) REPLACE_STRPTIME=GNULIB_PORTCHECK; AC_SUBST([REPLACE_STRPTIME]) REPLACE_TIMEGM=GNULIB_PORTCHECK; AC_SUBST([REPLACE_TIMEGM]) diff --git a/m4/tm_gmtoff.m4 b/m4/tm_gmtoff.m4 index cb0b3c884..911af0a40 100644 --- a/m4/tm_gmtoff.m4 +++ b/m4/tm_gmtoff.m4 @@ -1,5 +1,5 @@ -# tm_gmtoff.m4 serial 2 -dnl Copyright (C) 2002 Free Software Foundation, Inc. +# tm_gmtoff.m4 serial 3 +dnl Copyright (C) 2002, 2009 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. @@ -7,7 +7,7 @@ dnl with or without modifications, as long as this notice is preserved. AC_DEFUN([gl_TM_GMTOFF], [ AC_CHECK_MEMBER([struct tm.tm_gmtoff], - [AC_DEFINE(HAVE_TM_GMTOFF, 1, + [AC_DEFINE([HAVE_TM_GMTOFF], [1], [Define if struct tm has the tm_gmtoff member.])], , [#include ]) diff --git a/m4/unistd_h.m4 b/m4/unistd_h.m4 index 568527365..96fddba7f 100644 --- a/m4/unistd_h.m4 +++ b/m4/unistd_h.m4 @@ -1,5 +1,5 @@ -# unistd_h.m4 serial 16 -dnl Copyright (C) 2006-2008 Free Software Foundation, Inc. +# unistd_h.m4 serial 18 +dnl Copyright (C) 2006-2009 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. @@ -48,6 +48,7 @@ AC_DEFUN([gl_UNISTD_H_DEFAULTS], GNULIB_GETPAGESIZE=0; AC_SUBST([GNULIB_GETPAGESIZE]) GNULIB_GETUSERSHELL=0; AC_SUBST([GNULIB_GETUSERSHELL]) GNULIB_LCHOWN=0; AC_SUBST([GNULIB_LCHOWN]) + GNULIB_LINK=0; AC_SUBST([GNULIB_LINK]) GNULIB_LSEEK=0; AC_SUBST([GNULIB_LSEEK]) GNULIB_READLINK=0; AC_SUBST([GNULIB_READLINK]) GNULIB_SLEEP=0; AC_SUBST([GNULIB_SLEEP]) @@ -63,6 +64,7 @@ AC_DEFUN([gl_UNISTD_H_DEFAULTS], HAVE_GETHOSTNAME=1; AC_SUBST([HAVE_GETHOSTNAME]) HAVE_GETPAGESIZE=1; AC_SUBST([HAVE_GETPAGESIZE]) HAVE_GETUSERSHELL=1; AC_SUBST([HAVE_GETUSERSHELL]) + HAVE_LINK=1; AC_SUBST([HAVE_LINK]) HAVE_READLINK=1; AC_SUBST([HAVE_READLINK]) HAVE_SLEEP=1; AC_SUBST([HAVE_SLEEP]) HAVE_DECL_ENVIRON=1; AC_SUBST([HAVE_DECL_ENVIRON]) @@ -71,6 +73,7 @@ AC_DEFUN([gl_UNISTD_H_DEFAULTS], HAVE_SYS_PARAM_H=0; AC_SUBST([HAVE_SYS_PARAM_H]) REPLACE_CHOWN=0; AC_SUBST([REPLACE_CHOWN]) REPLACE_CLOSE=0; AC_SUBST([REPLACE_CLOSE]) + REPLACE_DUP2=0; AC_SUBST([REPLACE_DUP2]) REPLACE_FCHDIR=0; AC_SUBST([REPLACE_FCHDIR]) REPLACE_GETCWD=0; AC_SUBST([REPLACE_GETCWD]) REPLACE_GETPAGESIZE=0; AC_SUBST([REPLACE_GETPAGESIZE]) diff --git a/m4/vasnprintf.m4 b/m4/vasnprintf.m4 new file mode 100644 index 000000000..3a1d1e010 --- /dev/null +++ b/m4/vasnprintf.m4 @@ -0,0 +1,276 @@ +# vasnprintf.m4 serial 29 +dnl Copyright (C) 2002-2004, 2006-2009 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_VASNPRINTF], +[ + AC_CHECK_FUNCS_ONCE([vasnprintf]) + if test $ac_cv_func_vasnprintf = no; then + gl_REPLACE_VASNPRINTF + fi +]) + +AC_DEFUN([gl_REPLACE_VASNPRINTF], +[ + AC_CHECK_FUNCS_ONCE([vasnprintf]) + AC_LIBOBJ([vasnprintf]) + AC_LIBOBJ([printf-args]) + AC_LIBOBJ([printf-parse]) + AC_LIBOBJ([asnprintf]) + if test $ac_cv_func_vasnprintf = yes; then + AC_DEFINE([REPLACE_VASNPRINTF], [1], + [Define if vasnprintf exists but is overridden by gnulib.]) + fi + gl_PREREQ_PRINTF_ARGS + gl_PREREQ_PRINTF_PARSE + gl_PREREQ_VASNPRINTF + gl_PREREQ_ASNPRINTF +]) + +# Prequisites of lib/printf-args.h, lib/printf-args.c. +AC_DEFUN([gl_PREREQ_PRINTF_ARGS], +[ + AC_REQUIRE([AC_TYPE_LONG_LONG_INT]) + AC_REQUIRE([gt_TYPE_WCHAR_T]) + AC_REQUIRE([gt_TYPE_WINT_T]) +]) + +# Prequisites of lib/printf-parse.h, lib/printf-parse.c. +AC_DEFUN([gl_PREREQ_PRINTF_PARSE], +[ + AC_REQUIRE([AC_TYPE_LONG_LONG_INT]) + AC_REQUIRE([gt_TYPE_WCHAR_T]) + AC_REQUIRE([gt_TYPE_WINT_T]) + AC_REQUIRE([AC_TYPE_SIZE_T]) + AC_CHECK_TYPE([ptrdiff_t], , + [AC_DEFINE([ptrdiff_t], [long], + [Define as the type of the result of subtracting two pointers, if the system doesn't define it.]) + ]) + AC_REQUIRE([gt_AC_TYPE_INTMAX_T]) +]) + +# Prerequisites of lib/vasnprintf.c. +AC_DEFUN_ONCE([gl_PREREQ_VASNPRINTF], +[ + AC_REQUIRE([AC_FUNC_ALLOCA]) + AC_REQUIRE([AC_TYPE_LONG_LONG_INT]) + AC_REQUIRE([gt_TYPE_WCHAR_T]) + AC_REQUIRE([gt_TYPE_WINT_T]) + AC_CHECK_FUNCS([snprintf strnlen wcslen wcsnlen mbrtowc wcrtomb]) + dnl Use the _snprintf function only if it is declared (because on NetBSD it + dnl is defined as a weak alias of snprintf; we prefer to use the latter). + AC_CHECK_DECLS([_snprintf], , , [#include ]) +]) + +# Extra prerequisites of lib/vasnprintf.c for supporting 'long double' +# arguments. +AC_DEFUN_ONCE([gl_PREREQ_VASNPRINTF_LONG_DOUBLE], +[ + AC_REQUIRE([gl_PRINTF_LONG_DOUBLE]) + case "$gl_cv_func_printf_long_double" in + *yes) + ;; + *) + AC_DEFINE([NEED_PRINTF_LONG_DOUBLE], [1], + [Define if the vasnprintf implementation needs special code for + 'long double' arguments.]) + ;; + esac +]) + +# Extra prerequisites of lib/vasnprintf.c for supporting infinite 'double' +# arguments. +AC_DEFUN([gl_PREREQ_VASNPRINTF_INFINITE_DOUBLE], +[ + AC_REQUIRE([gl_PRINTF_INFINITE]) + case "$gl_cv_func_printf_infinite" in + *yes) + ;; + *) + AC_DEFINE([NEED_PRINTF_INFINITE_DOUBLE], [1], + [Define if the vasnprintf implementation needs special code for + infinite 'double' arguments.]) + ;; + esac +]) + +# Extra prerequisites of lib/vasnprintf.c for supporting infinite 'long double' +# arguments. +AC_DEFUN([gl_PREREQ_VASNPRINTF_INFINITE_LONG_DOUBLE], +[ + AC_REQUIRE([gl_PRINTF_INFINITE_LONG_DOUBLE]) + dnl There is no need to set NEED_PRINTF_INFINITE_LONG_DOUBLE if + dnl NEED_PRINTF_LONG_DOUBLE is already set. + AC_REQUIRE([gl_PREREQ_VASNPRINTF_LONG_DOUBLE]) + case "$gl_cv_func_printf_long_double" in + *yes) + case "$gl_cv_func_printf_infinite_long_double" in + *yes) + ;; + *) + AC_DEFINE([NEED_PRINTF_INFINITE_LONG_DOUBLE], [1], + [Define if the vasnprintf implementation needs special code for + infinite 'long double' arguments.]) + ;; + esac + ;; + esac +]) + +# Extra prerequisites of lib/vasnprintf.c for supporting the 'a' directive. +AC_DEFUN([gl_PREREQ_VASNPRINTF_DIRECTIVE_A], +[ + AC_REQUIRE([gl_PRINTF_DIRECTIVE_A]) + case "$gl_cv_func_printf_directive_a" in + *yes) + ;; + *) + AC_DEFINE([NEED_PRINTF_DIRECTIVE_A], [1], + [Define if the vasnprintf implementation needs special code for + the 'a' and 'A' directives.]) + AC_CHECK_FUNCS([nl_langinfo]) + ;; + esac +]) + +# Extra prerequisites of lib/vasnprintf.c for supporting the 'F' directive. +AC_DEFUN([gl_PREREQ_VASNPRINTF_DIRECTIVE_F], +[ + AC_REQUIRE([gl_PRINTF_DIRECTIVE_F]) + case "$gl_cv_func_printf_directive_f" in + *yes) + ;; + *) + AC_DEFINE([NEED_PRINTF_DIRECTIVE_F], [1], + [Define if the vasnprintf implementation needs special code for + the 'F' directive.]) + ;; + esac +]) + +# Extra prerequisites of lib/vasnprintf.c for supporting the 'ls' directive. +AC_DEFUN([gl_PREREQ_VASNPRINTF_DIRECTIVE_LS], +[ + AC_REQUIRE([gl_PRINTF_DIRECTIVE_LS]) + case "$gl_cv_func_printf_directive_ls" in + *yes) + ;; + *) + AC_DEFINE([NEED_PRINTF_DIRECTIVE_LS], [1], + [Define if the vasnprintf implementation needs special code for + the 'ls' directive.]) + ;; + esac +]) + +# Extra prerequisites of lib/vasnprintf.c for supporting the ' flag. +AC_DEFUN([gl_PREREQ_VASNPRINTF_FLAG_GROUPING], +[ + AC_REQUIRE([gl_PRINTF_FLAG_GROUPING]) + case "$gl_cv_func_printf_flag_grouping" in + *yes) + ;; + *) + AC_DEFINE([NEED_PRINTF_FLAG_GROUPING], [1], + [Define if the vasnprintf implementation needs special code for the + ' flag.]) + ;; + esac +]) + +# Extra prerequisites of lib/vasnprintf.c for supporting the '-' flag. +AC_DEFUN([gl_PREREQ_VASNPRINTF_FLAG_LEFTADJUST], +[ + AC_REQUIRE([gl_PRINTF_FLAG_LEFTADJUST]) + case "$gl_cv_func_printf_flag_leftadjust" in + *yes) + ;; + *) + AC_DEFINE([NEED_PRINTF_FLAG_LEFTADJUST], [1], + [Define if the vasnprintf implementation needs special code for the + '-' flag.]) + ;; + esac +]) + +# Extra prerequisites of lib/vasnprintf.c for supporting the 0 flag. +AC_DEFUN([gl_PREREQ_VASNPRINTF_FLAG_ZERO], +[ + AC_REQUIRE([gl_PRINTF_FLAG_ZERO]) + case "$gl_cv_func_printf_flag_zero" in + *yes) + ;; + *) + AC_DEFINE([NEED_PRINTF_FLAG_ZERO], [1], + [Define if the vasnprintf implementation needs special code for the + 0 flag.]) + ;; + esac +]) + +# Extra prerequisites of lib/vasnprintf.c for supporting large precisions. +AC_DEFUN([gl_PREREQ_VASNPRINTF_PRECISION], +[ + AC_REQUIRE([gl_PRINTF_PRECISION]) + case "$gl_cv_func_printf_precision" in + *yes) + ;; + *) + AC_DEFINE([NEED_PRINTF_UNBOUNDED_PRECISION], [1], + [Define if the vasnprintf implementation needs special code for + supporting large precisions without arbitrary bounds.]) + AC_DEFINE([NEED_PRINTF_DOUBLE], [1], + [Define if the vasnprintf implementation needs special code for + 'double' arguments.]) + AC_DEFINE([NEED_PRINTF_LONG_DOUBLE], [1], + [Define if the vasnprintf implementation needs special code for + 'long double' arguments.]) + ;; + esac +]) + +# Extra prerequisites of lib/vasnprintf.c for surviving out-of-memory +# conditions. +AC_DEFUN([gl_PREREQ_VASNPRINTF_ENOMEM], +[ + AC_REQUIRE([gl_PRINTF_ENOMEM]) + case "$gl_cv_func_printf_enomem" in + *yes) + ;; + *) + AC_DEFINE([NEED_PRINTF_ENOMEM], [1], + [Define if the vasnprintf implementation needs special code for + surviving out-of-memory conditions.]) + AC_DEFINE([NEED_PRINTF_DOUBLE], [1], + [Define if the vasnprintf implementation needs special code for + 'double' arguments.]) + AC_DEFINE([NEED_PRINTF_LONG_DOUBLE], [1], + [Define if the vasnprintf implementation needs special code for + 'long double' arguments.]) + ;; + esac +]) + +# Prerequisites of lib/vasnprintf.c including all extras for POSIX compliance. +AC_DEFUN([gl_PREREQ_VASNPRINTF_WITH_EXTRAS], +[ + AC_REQUIRE([gl_PREREQ_VASNPRINTF]) + gl_PREREQ_VASNPRINTF_LONG_DOUBLE + gl_PREREQ_VASNPRINTF_INFINITE_DOUBLE + gl_PREREQ_VASNPRINTF_INFINITE_LONG_DOUBLE + gl_PREREQ_VASNPRINTF_DIRECTIVE_A + gl_PREREQ_VASNPRINTF_DIRECTIVE_F + gl_PREREQ_VASNPRINTF_DIRECTIVE_LS + gl_PREREQ_VASNPRINTF_FLAG_GROUPING + gl_PREREQ_VASNPRINTF_FLAG_LEFTADJUST + gl_PREREQ_VASNPRINTF_FLAG_ZERO + gl_PREREQ_VASNPRINTF_PRECISION + gl_PREREQ_VASNPRINTF_ENOMEM +]) + +# Prerequisites of lib/asnprintf.c. +AC_DEFUN([gl_PREREQ_ASNPRINTF], +[ +]) diff --git a/m4/visibility.m4 b/m4/visibility.m4 new file mode 100644 index 000000000..70bca5643 --- /dev/null +++ b/m4/visibility.m4 @@ -0,0 +1,52 @@ +# visibility.m4 serial 2 (gettext-0.18) +dnl Copyright (C) 2005, 2008 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. + +dnl Tests whether the compiler supports the command-line option +dnl -fvisibility=hidden and the function and variable attributes +dnl __attribute__((__visibility__("hidden"))) and +dnl __attribute__((__visibility__("default"))). +dnl Does *not* test for __visibility__("protected") - which has tricky +dnl semantics (see the 'vismain' test in glibc) and does not exist e.g. on +dnl MacOS X. +dnl Does *not* test for __visibility__("internal") - which has processor +dnl dependent semantics. +dnl Does *not* test for #pragma GCC visibility push(hidden) - which is +dnl "really only recommended for legacy code". +dnl Set the variable CFLAG_VISIBILITY. +dnl Defines and sets the variable HAVE_VISIBILITY. + +AC_DEFUN([gl_VISIBILITY], +[ + AC_REQUIRE([AC_PROG_CC]) + CFLAG_VISIBILITY= + HAVE_VISIBILITY=0 + if test -n "$GCC"; then + AC_MSG_CHECKING([for simple visibility declarations]) + AC_CACHE_VAL([gl_cv_cc_visibility], [ + gl_save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -fvisibility=hidden" + AC_TRY_COMPILE( + [extern __attribute__((__visibility__("hidden"))) int hiddenvar; + extern __attribute__((__visibility__("default"))) int exportedvar; + extern __attribute__((__visibility__("hidden"))) int hiddenfunc (void); + extern __attribute__((__visibility__("default"))) int exportedfunc (void);], + [], + [gl_cv_cc_visibility=yes], + [gl_cv_cc_visibility=no]) + CFLAGS="$gl_save_CFLAGS"]) + AC_MSG_RESULT([$gl_cv_cc_visibility]) + if test $gl_cv_cc_visibility = yes; then + CFLAG_VISIBILITY="-fvisibility=hidden" + HAVE_VISIBILITY=1 + fi + fi + AC_SUBST([CFLAG_VISIBILITY]) + AC_SUBST([HAVE_VISIBILITY]) + AC_DEFINE_UNQUOTED([HAVE_VISIBILITY], [$HAVE_VISIBILITY], + [Define to 1 or 0, depending whether the compiler supports simple visibility declarations.]) +]) diff --git a/m4/vsnprintf.m4 b/m4/vsnprintf.m4 new file mode 100644 index 000000000..3b37d460b --- /dev/null +++ b/m4/vsnprintf.m4 @@ -0,0 +1,40 @@ +# vsnprintf.m4 serial 5 +dnl Copyright (C) 2002-2004, 2007-2008 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_VSNPRINTF], +[ + AC_REQUIRE([gl_STDIO_H_DEFAULTS]) + gl_cv_func_vsnprintf_usable=no + AC_CHECK_FUNCS([vsnprintf]) + if test $ac_cv_func_vsnprintf = yes; then + gl_SNPRINTF_SIZE1 + case "$gl_cv_func_snprintf_size1" in + *yes) + gl_cv_func_vsnprintf_usable=yes + ;; + esac + fi + if test $gl_cv_func_vsnprintf_usable = no; then + gl_REPLACE_VSNPRINTF + fi + AC_CHECK_DECLS_ONCE([vsnprintf]) + if test $ac_cv_have_decl_vsnprintf = no; then + HAVE_DECL_VSNPRINTF=0 + fi +]) + +AC_DEFUN([gl_REPLACE_VSNPRINTF], +[ + AC_REQUIRE([gl_STDIO_H_DEFAULTS]) + AC_LIBOBJ([vsnprintf]) + if test $ac_cv_func_vsnprintf = yes; then + REPLACE_VSNPRINTF=1 + fi + gl_PREREQ_VSNPRINTF +]) + +# Prerequisites of lib/vsnprintf.c. +AC_DEFUN([gl_PREREQ_VSNPRINTF], [:]) diff --git a/m4/wchar.m4 b/m4/wchar.m4 index ba8ee6ab7..2e52a82ac 100644 --- a/m4/wchar.m4 +++ b/m4/wchar.m4 @@ -1,13 +1,13 @@ dnl A placeholder for ISO C99 , for platforms that have issues. -dnl Copyright (C) 2007-2008 Free Software Foundation, Inc. +dnl Copyright (C) 2007-2009 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl Written by Eric Blake. -# wchar.m4 serial 22 +# wchar.m4 serial 23 AC_DEFUN([gl_WCHAR_H], [ @@ -73,27 +73,28 @@ AC_DEFUN([gl_WCHAR_H_DEFAULTS], GNULIB_WCSNRTOMBS=0; AC_SUBST([GNULIB_WCSNRTOMBS]) GNULIB_WCWIDTH=0; AC_SUBST([GNULIB_WCWIDTH]) dnl Assume proper GNU behavior unless another module says otherwise. - HAVE_BTOWC=1; AC_SUBST([HAVE_BTOWC]) - HAVE_MBSINIT=1; AC_SUBST([HAVE_MBSINIT]) - HAVE_MBRTOWC=1; AC_SUBST([HAVE_MBRTOWC]) - HAVE_MBRLEN=1; AC_SUBST([HAVE_MBRLEN]) - HAVE_MBSRTOWCS=1; AC_SUBST([HAVE_MBSRTOWCS]) - HAVE_MBSNRTOWCS=1; AC_SUBST([HAVE_MBSNRTOWCS]) - HAVE_WCRTOMB=1; AC_SUBST([HAVE_WCRTOMB]) - HAVE_WCSRTOMBS=1; AC_SUBST([HAVE_WCSRTOMBS]) - HAVE_WCSNRTOMBS=1; AC_SUBST([HAVE_WCSNRTOMBS]) - HAVE_DECL_WCTOB=1; AC_SUBST([HAVE_DECL_WCTOB]) - HAVE_DECL_WCWIDTH=1; AC_SUBST([HAVE_DECL_WCWIDTH]) - REPLACE_MBSTATE_T=0; AC_SUBST([REPLACE_MBSTATE_T]) - REPLACE_BTOWC=0; AC_SUBST([REPLACE_BTOWC]) - REPLACE_WCTOB=0; AC_SUBST([REPLACE_WCTOB]) - REPLACE_MBSINIT=0; AC_SUBST([REPLACE_MBSINIT]) - REPLACE_MBRTOWC=0; AC_SUBST([REPLACE_MBRTOWC]) - REPLACE_MBRLEN=0; AC_SUBST([REPLACE_MBRLEN]) - REPLACE_MBSRTOWCS=0; AC_SUBST([REPLACE_MBSRTOWCS]) - REPLACE_MBSNRTOWCS=0;AC_SUBST([REPLACE_MBSNRTOWCS]) - REPLACE_WCRTOMB=0; AC_SUBST([REPLACE_WCRTOMB]) - REPLACE_WCSRTOMBS=0; AC_SUBST([REPLACE_WCSRTOMBS]) - REPLACE_WCWIDTH=0; AC_SUBST([REPLACE_WCWIDTH]) - WCHAR_H=''; AC_SUBST([WCHAR_H]) + HAVE_BTOWC=1; AC_SUBST([HAVE_BTOWC]) + HAVE_MBSINIT=1; AC_SUBST([HAVE_MBSINIT]) + HAVE_MBRTOWC=1; AC_SUBST([HAVE_MBRTOWC]) + HAVE_MBRLEN=1; AC_SUBST([HAVE_MBRLEN]) + HAVE_MBSRTOWCS=1; AC_SUBST([HAVE_MBSRTOWCS]) + HAVE_MBSNRTOWCS=1; AC_SUBST([HAVE_MBSNRTOWCS]) + HAVE_WCRTOMB=1; AC_SUBST([HAVE_WCRTOMB]) + HAVE_WCSRTOMBS=1; AC_SUBST([HAVE_WCSRTOMBS]) + HAVE_WCSNRTOMBS=1; AC_SUBST([HAVE_WCSNRTOMBS]) + HAVE_DECL_WCTOB=1; AC_SUBST([HAVE_DECL_WCTOB]) + HAVE_DECL_WCWIDTH=1; AC_SUBST([HAVE_DECL_WCWIDTH]) + REPLACE_MBSTATE_T=0; AC_SUBST([REPLACE_MBSTATE_T]) + REPLACE_BTOWC=0; AC_SUBST([REPLACE_BTOWC]) + REPLACE_WCTOB=0; AC_SUBST([REPLACE_WCTOB]) + REPLACE_MBSINIT=0; AC_SUBST([REPLACE_MBSINIT]) + REPLACE_MBRTOWC=0; AC_SUBST([REPLACE_MBRTOWC]) + REPLACE_MBRLEN=0; AC_SUBST([REPLACE_MBRLEN]) + REPLACE_MBSRTOWCS=0; AC_SUBST([REPLACE_MBSRTOWCS]) + REPLACE_MBSNRTOWCS=0; AC_SUBST([REPLACE_MBSNRTOWCS]) + REPLACE_WCRTOMB=0; AC_SUBST([REPLACE_WCRTOMB]) + REPLACE_WCSRTOMBS=0; AC_SUBST([REPLACE_WCSRTOMBS]) + REPLACE_WCSNRTOMBS=0; AC_SUBST([REPLACE_WCSNRTOMBS]) + REPLACE_WCWIDTH=0; AC_SUBST([REPLACE_WCWIDTH]) + WCHAR_H=''; AC_SUBST([WCHAR_H]) ]) diff --git a/m4/wchar_t.m4 b/m4/wchar_t.m4 new file mode 100644 index 000000000..fb27a7f65 --- /dev/null +++ b/m4/wchar_t.m4 @@ -0,0 +1,20 @@ +# wchar_t.m4 serial 3 (gettext-0.18) +dnl Copyright (C) 2002-2003, 2008, 2009 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. +dnl Test whether has the 'wchar_t' type. +dnl Prerequisite: AC_PROG_CC + +AC_DEFUN([gt_TYPE_WCHAR_T], +[ + AC_CACHE_CHECK([for wchar_t], [gt_cv_c_wchar_t], + [AC_TRY_COMPILE([#include + wchar_t foo = (wchar_t)'\0';], , + [gt_cv_c_wchar_t=yes], [gt_cv_c_wchar_t=no])]) + if test $gt_cv_c_wchar_t = yes; then + AC_DEFINE([HAVE_WCHAR_T], [1], [Define if you have the 'wchar_t' type.]) + fi +]) diff --git a/m4/wint_t.m4 b/m4/wint_t.m4 index 0026a1318..47a4363d7 100644 --- a/m4/wint_t.m4 +++ b/m4/wint_t.m4 @@ -1,5 +1,5 @@ -# wint_t.m4 serial 3 (gettext-0.18) -dnl Copyright (C) 2003, 2007-2008 Free Software Foundation, Inc. +# wint_t.m4 serial 4 (gettext-0.18) +dnl Copyright (C) 2003, 2007-2009 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. @@ -23,6 +23,6 @@ AC_DEFUN([gt_TYPE_WINT_T], wint_t foo = (wchar_t)'\0';], , [gt_cv_c_wint_t=yes], [gt_cv_c_wint_t=no])]) if test $gt_cv_c_wint_t = yes; then - AC_DEFINE([HAVE_WINT_T], 1, [Define if you have the 'wint_t' type.]) + AC_DEFINE([HAVE_WINT_T], [1], [Define if you have the 'wint_t' type.]) fi ]) diff --git a/m4/xsize.m4 b/m4/xsize.m4 new file mode 100644 index 000000000..631893cf5 --- /dev/null +++ b/m4/xsize.m4 @@ -0,0 +1,13 @@ +# xsize.m4 serial 4 +dnl Copyright (C) 2003-2004, 2008 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_XSIZE], +[ + dnl Prerequisites of lib/xsize.h. + AC_REQUIRE([gl_SIZE_MAX]) + AC_REQUIRE([AC_C_INLINE]) + AC_CHECK_HEADERS([stdint.h]) +]) diff --git a/guile-config/ChangeLog-2008 b/meta/ChangeLog-2008 similarity index 100% rename from guile-config/ChangeLog-2008 rename to meta/ChangeLog-2008 diff --git a/meta/Makefile.am b/meta/Makefile.am new file mode 100644 index 000000000..c8bdacc92 --- /dev/null +++ b/meta/Makefile.am @@ -0,0 +1,35 @@ +## Process this file with Automake to create Makefile.in +## Jim Blandy --- September 1997 +## +## Copyright (C) 1998, 1999, 2001, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. +## +## This file is part of GUILE. +## +## GUILE is free software; you can redistribute it and/or modify it +## under the terms of the GNU Lesser General Public License as +## published by the Free Software Foundation; either version 3, or +## (at your option) any later version. +## +## GUILE is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with GUILE; see the file COPYING.LESSER. If not, +## write to the Free Software Foundation, Inc., 51 Franklin Street, +## Fifth Floor, Boston, MA 02110-1301 USA + +bin_SCRIPTS = guile-config +EXTRA_DIST= $(bin_SCRIPTS) \ + guile.m4 ChangeLog-2008 \ + guile-2.0.pc.in guile-2.0-uninstalled.pc.in \ + guile-tools.in + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = guile-2.0.pc + +## FIXME: in the future there will be direct automake support for +## doing this. When that happens, switch over. +aclocaldir = $(datadir)/aclocal +aclocal_DATA = guile.m4 diff --git a/meta/gdb-uninstalled-guile.in b/meta/gdb-uninstalled-guile.in new file mode 100644 index 000000000..1151dbc3a --- /dev/null +++ b/meta/gdb-uninstalled-guile.in @@ -0,0 +1,38 @@ +#!/bin/sh + +# Copyright (C) 2002, 2006, 2008 Free Software Foundation +# +# This file is part of GUILE. +# +# GUILE is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as +# published by the Free Software Foundation; either version 3, or +# (at your option) any later version. +# +# GUILE is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with GUILE; see the file COPYING.LESSER. If not, +# write to the Free Software Foundation, Inc., 51 Franklin Street, +# Fifth Floor, Boston, MA 02110-1301 USA + +# Commentary: + +# Usage: gdb-uninstalled-guile [ARGS] +# +# This script runs Guile from the build tree under GDB. See +# ./guile for more information. +# +# In addition to running ./gdb-uninstalled-guile, sometimes it's useful to +# run e.g. ./check-guile -i meta/gdb-uninstalled-guile foo.test. + +# Code: + +set -e +# env (set by configure) +top_builddir="@top_builddir_absolute@" +exec ${top_builddir}/meta/uninstalled-env libtool --mode=execute \ + gdb --args ${top_builddir}/libguile/guile "$@" diff --git a/meta/guile-2.0-uninstalled.pc.in b/meta/guile-2.0-uninstalled.pc.in new file mode 100644 index 000000000..50d337fd3 --- /dev/null +++ b/meta/guile-2.0-uninstalled.pc.in @@ -0,0 +1,8 @@ +builddir=@abs_top_builddir@ +srcdir=@abs_top_srcdir@ + +Name: GNU Guile (uninstalled) +Description: GNU's Ubiquitous Intelligent Language for Extension (uninstalled) +Version: @GUILE_VERSION@ +Libs: -L${builddir}/libguile -lguile @GUILE_LIBS@ +Cflags: -I${srcdir} -I${builddir} @GUILE_CFLAGS@ diff --git a/guile-1.8.pc.in b/meta/guile-2.0.pc.in similarity index 93% rename from guile-1.8.pc.in rename to meta/guile-2.0.pc.in index 15c83d84b..1b43cbc5e 100644 --- a/guile-1.8.pc.in +++ b/meta/guile-2.0.pc.in @@ -4,6 +4,7 @@ libdir=@libdir@ includedir=@includedir@ datarootdir=@datarootdir@ datadir=@datadir@ +pkgdatadir=@datadir@/guile sitedir=@sitedir@ libguileinterface=@LIBGUILE_INTERFACE@ diff --git a/guile-config/guile-config.in b/meta/guile-config old mode 100644 new mode 100755 similarity index 50% rename from guile-config/guile-config.in rename to meta/guile-config index b782292d8..6c640c40c --- a/guile-config/guile-config.in +++ b/meta/guile-config @@ -1,15 +1,15 @@ -#!@-bindir-@/guile \ --e main -s +#!/bin/sh +exec guile -e main -s $0 "$@" !# ;;;; guile-config --- utility for linking programs with Guile ;;;; Jim Blandy --- September 1997 ;;;; -;;;; Copyright (C) 1998, 2001, 2004, 2005, 2006, 2008 Free Software Foundation, Inc. +;;;; Copyright (C) 1998, 2001, 2004, 2005, 2006, 2008, 2009 Free Software Foundation, Inc. ;;;; ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -17,16 +17,14 @@ ;;;; Lesser General Public License for more details. ;;;; ;;;; You should have received a copy of the GNU Lesser General Public -;;;; License along with this library; if not, write to the Free Software -;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;;;; License along with this library; if not, write to the Free +;;;; Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;;;; Boston, MA 02110-1301 USA -;;; TODO: -;;; * Add some plausible structure for returning the right exit status, -;;; just something that encourages people to do the correct thing. -;;; * Implement the static library support. This requires that -;;; some portion of the module system be done. +;;; This script has been deprecated. Just use pkg-config. -(use-modules (ice-9 string-fun)) +(use-modules (ice-9 popen) + (ice-9 rdelim)) ;;;; main function, command-line processing @@ -47,7 +45,6 @@ (define program-name #f) (define subcommand-name #f) -(define program-version "@-GUILE_VERSION-@") ;;; Given an executable path PATH, set program-name to something ;;; appropriate f or use in error messages (i.e., with leading @@ -74,8 +71,24 @@ (dle " " p " --help - show usage info (this message)") (dle " " p " --help SUBCOMMAND - show help for SUBCOMMAND"))) +(define guile-module "guile-2.0") + +(define (pkg-config . args) + (let* ((real-args (cons "pkg-config" args)) + (pipe (apply open-pipe* OPEN_READ real-args)) + (output (read-delimited "" pipe)) + (ret (close-pipe pipe))) + (case (status:exit-val ret) + ((0) (if (eof-object? output) "" output)) + (else (display-line-error + (format #f "error: ~s exited with non-zero error code ~A" + (cons "pkg-config" args) (status:exit-val ret))) + ;; assume pkg-config sent diagnostics to stdout + (exit (status:exit-val ret)))))) + (define (show-version args) - (display-line-error program-name " - Guile version " program-version)) + (format (current-error-port) "~A - Guile version ~A" + program-name (pkg-config "--modversion" guile-module))) (define (help-version) (let ((dle display-line-error)) @@ -98,69 +111,7 @@ ;;; now, we're just going to reach into Guile's configuration info and ;;; hack it out. (define (build-link args) - - ;; If PATH has the form FOO/libBAR.a, return the substring - ;; BAR, otherwise return #f. - (define (match-lib path) - (let* ((base (basename path)) - (len (string-length base))) - (if (and (> len 5) - (string=? (substring base 0 3) "lib") - (string=? (substring base (- len 2)) ".a")) - (substring base 3 (- len 2)) - #f))) - - (if (> (length args) 0) - (error - (string-append program-name - " link: arguments to subcommand not yet implemented"))) - - (let ((libdir (get-build-info 'libdir)) - (other-flags - (let loop ((libs - ;; Get the string of linker flags we used to build - ;; Guile, and break it up into a list. - (separate-fields-discarding-char #\space - (get-build-info 'LIBS) - list))) - - (cond - ((null? libs) '()) - - ;; Turn any "FOO/libBAR.a" elements into "-lBAR". - ((match-lib (car libs)) - => (lambda (bar) - (cons (string-append "-l" bar) - (loop (cdr libs))))) - - ;; Remove any empty strings that may have seeped in there. - ((string=? (car libs) "") (loop (cdr libs))) - - (else (cons (car libs) (loop (cdr libs)))))))) - - ;; Include libguile itself in the list, along with the directory - ;; it was installed in, but do *not* add /usr/lib since that may - ;; prevent other programs from specifying non-/usr/lib versions - ;; via their foo-config scripts. If *any* app puts -L/usr/lib in - ;; the output of its foo-config script then it may prevent the use - ;; a non-/usr/lib install of anything that also has a /usr/lib - ;; install. For now we hard-code /usr/lib, but later maybe we can - ;; do something more dynamic (i.e. what do we need. - - ;; Display the flags, separated by spaces. - (display (string-join - (list - (get-build-info 'CFLAGS) - (if (or (string=? libdir "/usr/lib") - (string=? libdir "/usr/lib/")) - "" - (string-append "-L" (get-build-info 'libdir))) - "-lguile -lltdl" - (string-join other-flags) - - ))) - (newline))) - + (display (apply pkg-config "--libs" guile-module args))) (define (help-link) (let ((dle display-line-error)) @@ -178,23 +129,7 @@ ;;;; The "compile" subcommand (define (build-compile args) - (if (> (length args) 0) - (error - (string-append program-name - " compile: no arguments expected"))) - - ;; See gcc manual wrt fixincludes. Search for "Use of - ;; `-I/usr/include' may cause trouble." For now we hard-code this. - ;; Later maybe we can do something more dynamic. - (display - (string-append - (if (not (string=? (get-build-info 'includedir) "/usr/include")) - (string-append "-I" (get-build-info 'includedir) " ") - " ") - - (get-build-info 'CFLAGS) - "\n" - ))) + (display (apply pkg-config "--cflags" guile-module args))) (define (help-compile) (let ((dle display-line-error)) @@ -211,44 +146,34 @@ (define (build-info args) (cond - ((null? args) (show-all-vars)) - ((null? (cdr args)) (show-var (car args))) - (else (display-line-error "Usage: " program-name " info [VAR]") + ((null? args) + (display-line-error "guile-config info with no args has been removed") + (quit 2)) + ((null? (cdr args)) + (cond + ((string=? (car args) "guileversion") + (display (pkg-config "--modversion" guile-module))) + (else + (display (pkg-config (format #f "--variable=~A" (car args)) + guile-module))))) + (else (display-line-error "Usage: " program-name " info VAR") (quit 2)))) -(define (show-all-vars) - (for-each (lambda (binding) - (display-line (car binding) " = " (cdr binding))) - %guile-build-info)) - -(define (show-var var) - (display (get-build-info (string->symbol var))) - (newline)) - (define (help-info) (let ((d display-line-error)) - (d "Usage: " program-name " info [VAR]") - (d "Display the value of the Makefile variable VAR used when Guile") - (d "was built. If VAR is omitted, display all Makefile variables.") + (d "Usage: " program-name " info VAR") + (d "Display the value of the pkg-config variable VAR used when Guile") + (d "was built.\n") (d "Use this command to find out where Guile was installed,") (d "where it will look for Scheme code at run-time, and so on."))) (define (usage-info) (display-line-error - " " program-name " info [VAR] - print Guile build directories")) + " " program-name " info VAR - print Guile build directories")) ;;;; trivial utilities -(define (get-build-info name) - (let ((val (assq name %guile-build-info))) - (if (not (pair? val)) - (begin - (display-line-error - program-name " " subcommand-name ": no such build-info: " name) - (quit 2))) - (cdr val))) - (define (display-line . args) (apply display-line-port (current-output-port) args)) diff --git a/meta/guile-tools.in b/meta/guile-tools.in new file mode 100755 index 000000000..51d103fe8 --- /dev/null +++ b/meta/guile-tools.in @@ -0,0 +1,116 @@ +#!/bin/sh +# -*- scheme -*- +exec guile $GUILE_FLAGS -e '(@@ (guile-tools) main)' -s "$0" "$@" +!# + +;;;; guile-tools --- running scripts bundled with Guile +;;;; Andy Wingo --- April 2009 +;;;; +;;;; Copyright (C) 2009 Free Software Foundation, Inc. +;;;; +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free +;;;; Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;;;; Boston, MA 02110-1301 USA + +(define-module (guile-tools)) + +;; Hack to provide scripts with the bug-report address. +(module-define! the-scm-module + '%guile-bug-report-address + "@PACKAGE_BUGREPORT@") + + +;; We can't import srfi-1, unfortunately, as we are used early in the +;; boot process, before the srfi-1 shlib is built. + +(define (fold kons seed seq) + (if (null? seq) + seed + (fold kons (kons (car seq) seed) (cdr seq)))) + +(define (help) + (display "\ +Usage: guile-tools --version + guile-tools --help + guile-tools PROGRAM [ARGS] + +If PROGRAM is \"list\" or omitted, display available scripts, otherwise +PROGRAM is run with ARGS. +")) + +(define (directory-files dir) + (if (and (file-exists? dir) (file-is-directory? dir)) + (let ((dir-stream (opendir dir))) + (let loop ((new (readdir dir-stream)) + (acc '())) + (if (eof-object? new) + (begin + (closedir dir-stream) + acc) + (loop (readdir dir-stream) + (if (or (string=? "." new) ; ignore + (string=? ".." new)) ; ignore + acc + (cons new acc)))))) + '())) + +(define (strip-extensions path) + (or-map (lambda (ext) + (and + (string-suffix? ext path) + (substring path 0 + (- (string-length path) (string-length ext))))) + (append %load-compiled-extensions %load-extensions))) + +(define (unique l) + (cond ((null? l) l) + ((null? (cdr l)) l) + ((equal? (car l) (cadr l)) (unique (cdr l))) + (else (cons (car l) (unique (cdr l)))))) + +;; for want of srfi-1 +(define (append-map f l) + (apply append (map f l))) + +(define (find-submodules head) + (let ((shead (map symbol->string head))) + (unique + (sort + (append-map (lambda (path) + (fold (lambda (x rest) + (let ((stripped (strip-extensions x))) + (if stripped (cons stripped rest) rest))) + '() + (directory-files + (fold (lambda (x y) (in-vicinity y x)) path shead)))) + %load-path) + stringsymbol s)))))) + (and (module-public-interface m) + m))) + +(define (main args) + (if (or (equal? (cdr args) '()) + (equal? (cdr args) '("list"))) + (list-scripts) + (let ((mod (find-script (cadr args)))) + (exit (apply (module-ref mod 'main) (cddr args)))))) diff --git a/pre-inst-guile.in b/meta/guile.in similarity index 66% rename from pre-inst-guile.in rename to meta/guile.in index 5adbabea2..ab1fe3706 100644 --- a/pre-inst-guile.in +++ b/meta/guile.in @@ -4,24 +4,24 @@ # # This file is part of GUILE. # -# GUILE 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, or +# GUILE is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as +# published by the Free Software Foundation; either version 3, or # (at your option) any later version. # # GUILE 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. +# GNU Lesser General Public License for more details. # -# You should have received a copy of the GNU General Public -# License along with GUILE; see the file COPYING. If not, write -# to the Free Software Foundation, Inc., 51 Franklin Street, Fifth -# Floor, Boston, MA 02110-1301 USA +# You should have received a copy of the GNU Lesser General Public +# License along with GUILE; see the file COPYING.LESSER. If not, +# write to the Free Software Foundation, Inc., 51 Franklin Street, +# Fifth Floor, Boston, MA 02110-1301 USA # Commentary: -# Usage: pre-inst-guile [ARGS] +# Usage: guile [ARGS] # # This script arranges for the environment to support, and eventaully execs, # the uninstalled binary guile executable located somewhere under libguile/, @@ -43,9 +43,9 @@ GUILE=${top_builddir}/libguile/guile export GUILE # do it -exec ${top_builddir}/pre-inst-guile-env $GUILE "$@" +exec ${top_builddir}/meta/uninstalled-env $GUILE "$@" # never reached exit 1 -# pre-inst-guile ends here +# guile ends here diff --git a/guile-config/guile.m4 b/meta/guile.m4 similarity index 96% rename from guile-config/guile.m4 rename to meta/guile.m4 index bcded2bdc..5ba725f51 100644 --- a/guile-config/guile.m4 +++ b/meta/guile.m4 @@ -3,9 +3,9 @@ ## Copyright (C) 1998,2001, 2006 Free Software Foundation, Inc. ## ## This library is free software; you can redistribute it and/or -## modify it under the terms of the GNU Lesser General Public -## License as published by the Free Software Foundation; either -## version 2.1 of the License, or (at your option) any later version. +## modify it under the terms of the GNU Lesser General Public License +## as published by the Free Software Foundation; either version 3 of +## the License, or (at your option) any later version. ## ## This library is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -14,7 +14,8 @@ ## ## You should have received a copy of the GNU Lesser General Public ## License along with this library; if not, write to the Free Software -## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +## 02110-1301 USA # serial 9 @@ -107,7 +108,7 @@ AC_DEFUN([GUILE_FLAGS], AC_DEFUN([GUILE_SITE_DIR], [AC_REQUIRE([GUILE_PROGS])dnl AC_MSG_CHECKING(for Guile site directory) - GUILE_SITE=`[$GUILE_CONFIG] info pkgdatadir`/site + GUILE_SITE=`[$GUILE_CONFIG] info sitedir` AC_MSG_RESULT($GUILE_SITE) AC_SUBST(GUILE_SITE) ]) diff --git a/pre-inst-guile-env.in b/meta/uninstalled-env.in similarity index 59% rename from pre-inst-guile-env.in rename to meta/uninstalled-env.in index bb0a81c06..9a6227230 100644 --- a/pre-inst-guile-env.in +++ b/meta/uninstalled-env.in @@ -1,13 +1,13 @@ #!/bin/sh -# Copyright (C) 2003, 2006, 2008 Free Software Foundation +# Copyright (C) 2003, 2006, 2008, 2009 Free Software Foundation # # This file is part of GUILE. # -# This script is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. +# This script is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -16,19 +16,20 @@ # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA -# NOTE: If you update this file, please update pre-inst-guile.in as +# NOTE: If you update this file, please update uninstalled.in as # well, if appropriate. -# Usage: pre-inst-guile-env [ARGS] +# Usage: uninstalled-env [ARGS] # This script arranges for the environment to support running Guile # from the build tree. The following env vars are modified (but not # clobbered): GUILE_LOAD_PATH, LTDL_LIBRARY_PATH, and PATH. -# Example: pre-inst-guile-env guile -c '(display "hello\n")' -# Example: ../../pre-inst-guile-env ./guile-test-foo +# Example: uninstalled-env guile -c '(display "hello\n")' +# Example: ../../uninstalled-env ./guile-test-foo # config subdirs_with_ltlibs="srfi guile-readline libguile" # maintain me @@ -66,9 +67,26 @@ else fi export GUILE_LOAD_PATH +if [ x"$GUILE_LOAD_COMPILED_PATH" = x ] +then + GUILE_LOAD_COMPILED_PATH="${top_builddir}/guile-readline:${top_builddir}:${top_builddir}/module" +else + for d in "${top_builddir}" "${top_builddir}/guile-readline" \ + "${top_builddir}/module" + do + # This hair prevents double inclusion. + # The ":" prevents prefix aliasing. + case x"$GUILE_LOAD_COMPILED_PATH" in + x*${d}:*) ;; + *) GUILE_LOAD_COMPILED_PATH="${d}:$GUILE_LOAD_COMPILED_PATH" ;; + esac + done +fi +export GUILE_LOAD_COMPILED_PATH + # Don't look in installed dirs for guile modules -if ( env | grep -v -q -E '^GUILE_SYSTEM_PATH=' ); then - export GUILE_SYSTEM_PATH= +if ( env | grep -v -q -E '^GUILE_SYSTEM_COMPILED_PATH=' ); then + export GUILE_SYSTEM_COMPILED_PATH= fi # handle LTDL_LIBRARY_PATH (no clobber) @@ -80,12 +98,21 @@ for dir in $subdirs_with_ltlibs ; do done LTDL_LIBRARY_PATH="${ltdl_prefix}$LTDL_LIBRARY_PATH" export LTDL_LIBRARY_PATH -DYLD_LIBRARY_PATH="${dyld_prefix}${top_builddir}/libguile/.libs:$DYLD_LIBRARY_PATH" +DYLD_LIBRARY_PATH="${dyld_prefix}$DYLD_LIBRARY_PATH" export DYLD_LIBRARY_PATH +if [ x"$PKG_CONFIG_PATH" = x ] +then + PKG_CONFIG_PATH="${top_builddir}/meta" +else + PKG_CONFIG_PATH="${top_builddir}/meta:$PKG_CONFIG_PATH" +fi +export PKG_CONFIG_PATH + # handle PATH (no clobber) -PATH="${top_builddir}/guile-config:${PATH}" PATH="${top_builddir}/libguile:${PATH}" +PATH="${top_srcdir}/meta:${PATH}" +PATH="${top_builddir}/meta:${PATH}" export PATH exec "$@" diff --git a/module/Makefile.am b/module/Makefile.am index 64a74482b..5ef00be37 100644 --- a/module/Makefile.am +++ b/module/Makefile.am @@ -4,55 +4,88 @@ ## ## This file is part of GUILE. ## -## GUILE 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, or +## GUILE is free software; you can redistribute it and/or modify it +## under the terms of the GNU Lesser General Public License as +## published by the Free Software Foundation; either version 3, or ## (at your option) any later version. ## ## GUILE 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. +## GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU General Public -## License along with GUILE; see the file COPYING. If not, write -## to the Free Software Foundation, Inc., 51 Franklin Street, Fifth -## Floor, Boston, MA 02110-1301 USA +## You should have received a copy of the GNU Lesser General Public +## License along with GUILE; see the file COPYING.LESSER. If not, +## write to the Free Software Foundation, Inc., 51 Franklin Street, +## Fifth Floor, Boston, MA 02110-1301 USA -# Build the compiler and VM support first to avoid stack overflows -# when building the rest. -SUBDIRS = . ice-9 srfi oop +include $(top_srcdir)/am/guilec # We're at the root of the module hierarchy. modpath = +# Compile psyntax and boot-9 first, so that we get the speed benefit in +# the rest of the compilation. Also, if there is too much switching back +# and forth between interpreted and compiled code, we end up using more +# of the C stack than the interpreter would have; so avoid that by +# putting these core modules first. + SOURCES = \ + ice-9/psyntax-pp.scm \ system/base/pmatch.scm system/base/syntax.scm \ system/base/compile.scm system/base/language.scm \ + system/base/message.scm \ \ - system/vm/debug.scm system/vm/frame.scm system/vm/instruction.scm \ - system/vm/objcode.scm system/vm/profile.scm system/vm/program.scm \ - system/vm/trace.scm system/vm/vm.scm \ + language/tree-il.scm \ + language/glil.scm language/assembly.scm \ \ - system/xref.scm \ - \ - system/repl/repl.scm system/repl/common.scm \ - system/repl/command.scm \ - \ - language/ghil.scm language/glil.scm language/assembly.scm \ - \ - $(SCHEME_LANG_SOURCES) $(ECMASCRIPT_LANG_SOURCES) \ - $(GHIL_LANG_SOURCES) $(GLIL_LANG_SOURCES) \ + $(SCHEME_LANG_SOURCES) \ + $(TREE_IL_LANG_SOURCES) \ + $(GLIL_LANG_SOURCES) \ $(ASSEMBLY_LANG_SOURCES) $(BYTECODE_LANG_SOURCES) \ - $(OBJCODE_LANG_SOURCES) $(VALUE_LANG_SOURCES) + $(OBJCODE_LANG_SOURCES) $(VALUE_LANG_SOURCES) \ + \ + $(ICE_9_SOURCES) \ + $(SRFI_SOURCES) \ + $(RNRS_SOURCES) \ + $(OOP_SOURCES) \ + $(SYSTEM_SOURCES) \ + $(SCRIPTS_SOURCES) \ + $(GHIL_LANG_SOURCES) \ + $(ECMASCRIPT_LANG_SOURCES) \ + $(BRAINFUCK_LANG_SOURCES) + +## test.scm is not currently installed. +EXTRA_DIST += ice-9/test.scm ice-9/compile-psyntax.scm ice-9/ChangeLog-2008 + +# We expect this to never be invoked when there is not already +# ice-9/psyntax-pp.scm in %load-path, since compile-psyntax.scm depends +# on ice-9/syncase.scm, which does `(load-from-path "ice-9/psyntax-pp.scm")'. +# In other words, to bootstrap this file, you need to do something like: +# GUILE_LOAD_PATH=/usr/local/share/guile/1.5.4 make psyntax-pp.scm +include $(top_srcdir)/am/pre-inst-guile +ice-9/psyntax-pp.scm: ice-9/psyntax.scm + $(preinstguile) --no-autocompile -s $(srcdir)/ice-9/compile-psyntax.scm \ + $(srcdir)/ice-9/psyntax.scm $(srcdir)/ice-9/psyntax-pp.scm SCHEME_LANG_SOURCES = \ - language/scheme/amatch.scm language/scheme/expand.scm \ - language/scheme/compile-ghil.scm language/scheme/spec.scm \ + language/scheme/compile-ghil.scm \ + language/scheme/spec.scm \ + language/scheme/compile-tree-il.scm \ + language/scheme/decompile-tree-il.scm \ language/scheme/inline.scm -GHIL_LANG_SOURCES = \ - language/ghil/spec.scm language/ghil/compile-glil.scm +TREE_IL_LANG_SOURCES = \ + language/tree-il/primitives.scm \ + language/tree-il/optimize.scm \ + language/tree-il/inline.scm \ + language/tree-il/fix-letrec.scm \ + language/tree-il/analyze.scm \ + language/tree-il/compile-glil.scm \ + language/tree-il/spec.scm + +GHIL_LANG_SOURCES = \ + language/ghil.scm language/ghil/spec.scm language/ghil/compile-glil.scm GLIL_LANG_SOURCES = \ language/glil/spec.scm language/glil/compile-assembly.scm \ @@ -77,14 +110,166 @@ ECMASCRIPT_LANG_SOURCES = \ language/ecmascript/parse-lalr.scm \ language/ecmascript/tokenize.scm \ language/ecmascript/parse.scm \ - language/ecmascript/spec.scm \ language/ecmascript/impl.scm \ language/ecmascript/base.scm \ language/ecmascript/function.scm \ language/ecmascript/array.scm \ - language/ecmascript/compile-ghil.scm + language/ecmascript/compile-tree-il.scm \ + language/ecmascript/spec.scm + +BRAINFUCK_LANG_SOURCES = \ + language/brainfuck/parse.scm \ + language/brainfuck/compile-scheme.scm \ + language/brainfuck/compile-tree-il.scm \ + language/brainfuck/spec.scm + +SCRIPTS_SOURCES = \ + scripts/PROGRAM.scm \ + scripts/autofrisk.scm \ + scripts/compile.scm \ + scripts/disassemble.scm \ + scripts/display-commentary.scm \ + scripts/doc-snarf.scm \ + scripts/frisk.scm \ + scripts/generate-autoload.scm \ + scripts/lint.scm \ + scripts/punify.scm \ + scripts/read-scheme-source.scm \ + scripts/read-text-outline.scm \ + scripts/use2dot.scm \ + scripts/snarf-check-and-output-texi.scm \ + scripts/summarize-guile-TODO.scm \ + scripts/scan-api.scm \ + scripts/api-diff.scm \ + scripts/read-rfc822.scm \ + scripts/snarf-guile-m4-docs.scm + +ICE_9_SOURCES = \ + ice-9/boot-9.scm \ + ice-9/r4rs.scm \ + ice-9/r5rs.scm \ + ice-9/and-let-star.scm \ + ice-9/calling.scm \ + ice-9/common-list.scm \ + ice-9/debug.scm \ + ice-9/debugger.scm \ + ice-9/documentation.scm \ + ice-9/emacs.scm \ + ice-9/expect.scm \ + ice-9/format.scm \ + ice-9/getopt-long.scm \ + ice-9/hcons.scm \ + ice-9/i18n.scm \ + ice-9/lineio.scm \ + ice-9/ls.scm \ + ice-9/mapping.scm \ + ice-9/match.scm \ + ice-9/networking.scm \ + ice-9/null.scm \ + ice-9/occam-channel.scm \ + ice-9/optargs.scm \ + ice-9/poe.scm \ + ice-9/popen.scm \ + ice-9/posix.scm \ + ice-9/q.scm \ + ice-9/rdelim.scm \ + ice-9/receive.scm \ + ice-9/regex.scm \ + ice-9/runq.scm \ + ice-9/rw.scm \ + ice-9/safe-r5rs.scm \ + ice-9/safe.scm \ + ice-9/session.scm \ + ice-9/slib.scm \ + ice-9/stack-catch.scm \ + ice-9/streams.scm \ + ice-9/string-fun.scm \ + ice-9/syncase.scm \ + ice-9/threads.scm \ + ice-9/buffered-input.scm \ + ice-9/time.scm \ + ice-9/history.scm \ + ice-9/channel.scm \ + ice-9/pretty-print.scm \ + ice-9/ftw.scm \ + ice-9/gap-buffer.scm \ + ice-9/weak-vector.scm \ + ice-9/deprecated.scm \ + ice-9/list.scm \ + ice-9/serialize.scm \ + ice-9/gds-server.scm + +SRFI_SOURCES = \ + srfi/srfi-1.scm \ + srfi/srfi-2.scm \ + srfi/srfi-4.scm \ + srfi/srfi-6.scm \ + srfi/srfi-8.scm \ + srfi/srfi-9.scm \ + srfi/srfi-10.scm \ + srfi/srfi-11.scm \ + srfi/srfi-13.scm \ + srfi/srfi-14.scm \ + srfi/srfi-16.scm \ + srfi/srfi-17.scm \ + srfi/srfi-18.scm \ + srfi/srfi-19.scm \ + srfi/srfi-26.scm \ + srfi/srfi-31.scm \ + srfi/srfi-34.scm \ + srfi/srfi-35.scm \ + srfi/srfi-37.scm \ + srfi/srfi-39.scm \ + srfi/srfi-60.scm \ + srfi/srfi-69.scm \ + srfi/srfi-88.scm \ + srfi/srfi-98.scm + +RNRS_SOURCES = \ + rnrs/bytevector.scm \ + rnrs/io/ports.scm + +EXTRA_DIST += scripts/ChangeLog-2008 +EXTRA_DIST += scripts/README + +OOP_SOURCES = \ + oop/goops.scm \ + oop/goops/active-slot.scm \ + oop/goops/compile.scm \ + oop/goops/composite-slot.scm \ + oop/goops/describe.scm \ + oop/goops/dispatch.scm \ + oop/goops/internal.scm \ + oop/goops/save.scm \ + oop/goops/stklos.scm \ + oop/goops/util.scm \ + oop/goops/accessors.scm \ + oop/goops/simple.scm + +SYSTEM_SOURCES = \ + system/vm/debug.scm system/vm/frame.scm system/vm/instruction.scm \ + system/vm/objcode.scm system/vm/profile.scm system/vm/program.scm \ + system/vm/trace.scm system/vm/vm.scm \ + \ + system/xref.scm \ + \ + system/repl/repl.scm system/repl/common.scm \ + system/repl/command.scm + +EXTRA_DIST += oop/ChangeLog-2008 NOCOMP_SOURCES = \ - system/repl/describe.scm - -include $(top_srcdir)/am/guilec + ice-9/gds-client.scm \ + ice-9/psyntax.scm \ + system/repl/describe.scm \ + ice-9/debugger/command-loop.scm \ + ice-9/debugger/commands.scm \ + ice-9/debugger/state.scm \ + ice-9/debugger/trc.scm \ + ice-9/debugger/utils.scm \ + ice-9/debugging/example-fns.scm \ + ice-9/debugging/ice-9-debugger-extensions.scm \ + ice-9/debugging/steps.scm \ + ice-9/debugging/trace.scm \ + ice-9/debugging/traps.scm \ + ice-9/debugging/trc.scm diff --git a/module/ice-9/Makefile.am b/module/ice-9/Makefile.am deleted file mode 100644 index 8c94d8320..000000000 --- a/module/ice-9/Makefile.am +++ /dev/null @@ -1,70 +0,0 @@ -## Process this file with automake to produce Makefile.in. -## -## Copyright (C) 1998,1999,2000,2001,2003, 2004, 2006, 2008 Free Software Foundation, Inc. -## -## This file is part of GUILE. -## -## GUILE 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, or -## (at your option) any later version. -## -## GUILE 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 GUILE; see the file COPYING. If not, write -## to the Free Software Foundation, Inc., 51 Franklin Street, Fifth -## Floor, Boston, MA 02110-1301 USA - -AUTOMAKE_OPTIONS = gnu - -SUBDIRS = debugger debugging - -# These should be installed and distributed. -modpath = ice-9 -# Compile psyntax and boot-9 first, so that we get the speed benefit in -# the rest of the compilation. Also, if there is too much switching back -# and forth between interpreted and compiled code, we end up using more -# of the C stack than the interpreter would have; so avoid that by -# putting these core modules first. -SOURCES = psyntax-pp.scm annotate.scm boot-9.scm \ - and-let-star.scm calling.scm common-list.scm \ - debug.scm debugger.scm documentation.scm emacs.scm expect.scm \ - format.scm getopt-long.scm hcons.scm i18n.scm \ - lineio.scm ls.scm mapping.scm match.scm \ - networking.scm null.scm occam-channel.scm optargs.scm poe.scm \ - popen.scm posix.scm q.scm r4rs.scm r5rs.scm \ - rdelim.scm receive.scm regex.scm runq.scm rw.scm \ - safe-r5rs.scm safe.scm session.scm slib.scm stack-catch.scm \ - streams.scm string-fun.scm syncase.scm threads.scm \ - buffered-input.scm time.scm history.scm channel.scm \ - pretty-print.scm ftw.scm gap-buffer.scm \ - weak-vector.scm deprecated.scm list.scm serialize.scm \ - gds-server.scm - -# gds-client is tight with the memoizer, so punt on it until it can be -# made portable. -# -# psyntax.scm needs help. fortunately it's only needed when recompiling -# psyntax-pp.scm. -NOCOMP_SOURCES = gds-client.scm psyntax.scm - -include $(top_srcdir)/am/guilec - -## test.scm is not currently installed. -EXTRA_DIST += test.scm compile-psyntax.scm ChangeLog-2008 - -TAGS_FILES = $(SOURCES) - -# We expect this to never be invoked when there is not already -# ice-9/psyntax-pp.scm in %load-path, since compile-psyntax.scm depends -# on ice-9/syncase.scm, which does `(load-from-path "ice-9/psyntax-pp.scm")'. -# In other words, to bootstrap this file, you need to do something like: -# GUILE_LOAD_PATH=/usr/local/share/guile/1.5.4 make psyntax-pp.scm -include $(top_srcdir)/am/pre-inst-guile -psyntax-pp.scm: psyntax.scm - $(preinstguile) -s $(srcdir)/compile-psyntax.scm \ - $(srcdir)/psyntax.scm $(srcdir)/psyntax-pp.scm diff --git a/module/ice-9/and-let-star.scm b/module/ice-9/and-let-star.scm index b8cb2a679..bfd597b1e 100644 --- a/module/ice-9/and-let-star.scm +++ b/module/ice-9/and-let-star.scm @@ -6,7 +6,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/module/ice-9/annotate.scm b/module/ice-9/annotate.scm deleted file mode 100644 index 30f49d710..000000000 --- a/module/ice-9/annotate.scm +++ /dev/null @@ -1,80 +0,0 @@ -;;;; Copyright (C) 2009 Free Software Foundation, Inc. -;;;; -;;;; This library is free software; you can redistribute it and/or -;;;; modify it under the terms of the GNU Lesser General Public -;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. -;;;; -;;;; This library is distributed in the hope that it will be useful, -;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;;;; Lesser General Public License for more details. -;;;; -;;;; You should have received a copy of the GNU Lesser General Public -;;;; License along with this library; if not, write to the Free Software -;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -;;;; - - -(define-module (ice-9 annotate) - :export ( annotation? annotate deannotate make-annotation - annotation-expression annotation-source annotation-stripped - set-annotation-stripped! - deannotate/source-properties)) - -(define - (make-vtable "prprpw" - (lambda (struct port) - (display "#" port)))) - -(define (annotation? x) - (and (struct? x) (eq? (struct-vtable x) ))) - -(define (make-annotation e s . stripped?) - (if (null? stripped?) - (make-struct 0 e s #f) - (apply make-struct 0 e s stripped?))) - -(define (annotation-expression a) - (struct-ref a 0)) -(define (annotation-source a) - (struct-ref a 1)) -(define (annotation-stripped a) - (struct-ref a 2)) -(define (set-annotation-stripped! a stripped?) - (struct-set! a 2 stripped?)) - -(define (annotate e) - (let ((p (if (pair? e) (source-properties e) #f)) - (out (cond ((and (list? e) (not (null? e))) - (map annotate e)) - ((pair? e) - (cons (annotate (car e)) (annotate (cdr e)))) - (else e)))) - (if (pair? p) - (make-annotation out p #f) - out))) - -(define (deannotate e) - (cond ((list? e) - (map deannotate e)) - ((pair? e) - (cons (deannotate (car e)) (deannotate (cdr e)))) - ((annotation? e) (deannotate (annotation-expression e))) - (else e))) - -(define (deannotate/source-properties e) - (cond ((list? e) - (map deannotate/source-properties e)) - ((pair? e) - (cons (deannotate/source-properties (car e)) - (deannotate/source-properties (cdr e)))) - ((annotation? e) - (let ((e (deannotate/source-properties (annotation-expression e))) - (source (annotation-source e))) - (if (pair? e) - (set-source-properties! e source)) - e)) - (else e))) diff --git a/module/ice-9/arrays.scm b/module/ice-9/arrays.scm index 7ddcc8ab8..f7f9e5eed 100644 --- a/module/ice-9/arrays.scm +++ b/module/ice-9/arrays.scm @@ -2,20 +2,19 @@ ;;;; Copyright (C) 1999, 2001, 2004, 2006 Free Software Foundation, Inc. ;;;; -;;;; 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 2, or (at your option) -;;;; any later version. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. ;;;; -;;;; This program is distributed in the hope that it will be useful, +;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;;; GNU General Public License for more details. +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. ;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this software; see the file COPYING. If not, write to -;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;;; Boston, MA 02110-1301 USA +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;;;; (define (array-shape a) diff --git a/module/ice-9/boot-9.scm b/module/ice-9/boot-9.scm index bb284cfbf..1f74d10ea 100644 --- a/module/ice-9/boot-9.scm +++ b/module/ice-9/boot-9.scm @@ -6,7 +6,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -33,85 +33,6 @@ -;;; {Features} -;;; - -(define (provide sym) - (if (not (memq sym *features*)) - (set! *features* (cons sym *features*)))) - -;; Return #t iff FEATURE is available to this Guile interpreter. In SLIB, -;; provided? also checks to see if the module is available. We should do that -;; too, but don't. - -(define (provided? feature) - (and (memq feature *features*) #t)) - -;; let format alias simple-format until the more complete version is loaded - -(define format simple-format) - -;; this is scheme wrapping the C code so the final pred call is a tail call, -;; per SRFI-13 spec -(define (string-any char_pred s . rest) - (let ((start (if (null? rest) - 0 (car rest))) - (end (if (or (null? rest) (null? (cdr rest))) - (string-length s) (cadr rest)))) - (if (and (procedure? char_pred) - (> end start) - (<= end (string-length s))) ;; let c-code handle range error - (or (string-any-c-code char_pred s start (1- end)) - (char_pred (string-ref s (1- end)))) - (string-any-c-code char_pred s start end)))) - -;; this is scheme wrapping the C code so the final pred call is a tail call, -;; per SRFI-13 spec -(define (string-every char_pred s . rest) - (let ((start (if (null? rest) - 0 (car rest))) - (end (if (or (null? rest) (null? (cdr rest))) - (string-length s) (cadr rest)))) - (if (and (procedure? char_pred) - (> end start) - (<= end (string-length s))) ;; let c-code handle range error - (and (string-every-c-code char_pred s start (1- end)) - (char_pred (string-ref s (1- end)))) - (string-every-c-code char_pred s start end)))) - -;; A variant of string-fill! that we keep for compatability -;; -(define (substring-fill! str start end fill) - (string-fill! str fill start end)) - - - -;; (eval-when (situation...) form...) -;; -;; Evaluate certain code based on the situation that eval-when is used -;; in. There are three situations defined. -;; -;; `load' triggers when a file is loaded via `load', or when a compiled -;; file is loaded. -;; -;; `compile' triggers when an expression is compiled. -;; -;; `eval' triggers when code is evaluated interactively, as at the REPL -;; or via the `compile' or `eval' procedures. - -;; NB: this macro is only ever expanded by the interpreter. The compiler -;; notices it and interprets the situations differently. -(define eval-when - (procedure->memoizing-macro - (lambda (exp env) - (let ((situations (cadr exp)) - (body (cddr exp))) - (if (or (memq 'load situations) - (memq 'eval situations)) - `(begin . ,body)))))) - - - ;; Before compiling, make sure any symbols are resolved in the (guile) ;; module, the primary location of those symbols, rather than in ;; (guile-user), the default module that we compile in. @@ -119,76 +40,6 @@ (eval-when (compile) (set-current-module (resolve-module '(guile)))) -;;; {Defmacros} -;;; -;;; Depends on: features, eval-case -;;; - -(define macro-table (make-weak-key-hash-table 61)) -(define xformer-table (make-weak-key-hash-table 61)) - -(define (defmacro? m) (hashq-ref macro-table m)) -(define (assert-defmacro?! m) (hashq-set! macro-table m #t)) -(define (defmacro-transformer m) (hashq-ref xformer-table m)) -(define (set-defmacro-transformer! m t) (hashq-set! xformer-table m t)) - -(define defmacro:transformer - (lambda (f) - (let* ((xform (lambda (exp env) - (copy-tree (apply f (cdr exp))))) - (a (procedure->memoizing-macro xform))) - (assert-defmacro?! a) - (set-defmacro-transformer! a f) - a))) - - -(define defmacro - (let ((defmacro-transformer - (lambda (name parms . body) - (let ((transformer `(lambda ,parms ,@body))) - `(eval-when - (eval load compile) - (define ,name (defmacro:transformer ,transformer))))))) - (defmacro:transformer defmacro-transformer))) - - -;; XXX - should the definition of the car really be looked up in the -;; current module? - -(define (macroexpand-1 e) - (cond - ((pair? e) (let* ((a (car e)) - (val (and (symbol? a) (local-ref (list a))))) - (if (defmacro? val) - (apply (defmacro-transformer val) (cdr e)) - e))) - (#t e))) - -(define (macroexpand e) - (cond - ((pair? e) (let* ((a (car e)) - (val (and (symbol? a) (local-ref (list a))))) - (if (defmacro? val) - (macroexpand (apply (defmacro-transformer val) (cdr e))) - e))) - (#t e))) - -(provide 'defmacro) - - - -;;; {Deprecation} -;;; -;;; Depends on: defmacro -;;; - -(defmacro begin-deprecated forms - (if (include-deprecated-features) - `(begin ,@forms) - (begin))) - - - ;;; {R4RS compliance} ;;; @@ -228,6 +79,287 @@ +;;; {Features} +;;; + +(define (provide sym) + (if (not (memq sym *features*)) + (set! *features* (cons sym *features*)))) + +;; Return #t iff FEATURE is available to this Guile interpreter. In SLIB, +;; provided? also checks to see if the module is available. We should do that +;; too, but don't. + +(define (provided? feature) + (and (memq feature *features*) #t)) + + + +;;; {and-map and or-map} +;;; +;;; (and-map fn lst) is like (and (fn (car lst)) (fn (cadr lst)) (fn...) ...) +;;; (or-map fn lst) is like (or (fn (car lst)) (fn (cadr lst)) (fn...) ...) +;;; + +;; and-map f l +;; +;; Apply f to successive elements of l until exhaustion or f returns #f. +;; If returning early, return #f. Otherwise, return the last value returned +;; by f. If f has never been called because l is empty, return #t. +;; +(define (and-map f lst) + (let loop ((result #t) + (l lst)) + (and result + (or (and (null? l) + result) + (loop (f (car l)) (cdr l)))))) + +;; or-map f l +;; +;; Apply f to successive elements of l until exhaustion or while f returns #f. +;; If returning early, return the return value of f. +;; +(define (or-map f lst) + (let loop ((result #f) + (l lst)) + (or result + (and (not (null? l)) + (loop (f (car l)) (cdr l)))))) + + + +;; let format alias simple-format until the more complete version is loaded + +(define format simple-format) + +;; this is scheme wrapping the C code so the final pred call is a tail call, +;; per SRFI-13 spec +(define (string-any char_pred s . rest) + (let ((start (if (null? rest) + 0 (car rest))) + (end (if (or (null? rest) (null? (cdr rest))) + (string-length s) (cadr rest)))) + (if (and (procedure? char_pred) + (> end start) + (<= end (string-length s))) ;; let c-code handle range error + (or (string-any-c-code char_pred s start (1- end)) + (char_pred (string-ref s (1- end)))) + (string-any-c-code char_pred s start end)))) + +;; this is scheme wrapping the C code so the final pred call is a tail call, +;; per SRFI-13 spec +(define (string-every char_pred s . rest) + (let ((start (if (null? rest) + 0 (car rest))) + (end (if (or (null? rest) (null? (cdr rest))) + (string-length s) (cadr rest)))) + (if (and (procedure? char_pred) + (> end start) + (<= end (string-length s))) ;; let c-code handle range error + (and (string-every-c-code char_pred s start (1- end)) + (char_pred (string-ref s (1- end)))) + (string-every-c-code char_pred s start end)))) + +;; A variant of string-fill! that we keep for compatability +;; +(define (substring-fill! str start end fill) + (string-fill! str fill start end)) + + + +;; Define a minimal stub of the module API for psyntax, before modules +;; have booted. +(define (module-name x) + '(guile)) +(define (module-define! module sym val) + (let ((v (hashq-ref (%get-pre-modules-obarray) sym))) + (if v + (variable-set! v val) + (hashq-set! (%get-pre-modules-obarray) sym + (make-variable val))))) +(define (module-ref module sym) + (let ((v (module-variable module sym))) + (if v (variable-ref v) (error "badness!" (pk module) (pk sym))))) +(define (resolve-module . args) + #f) + +;; Input hook to syncase -- so that we might be able to pass annotated +;; expressions in. Currently disabled. Maybe we should just use +;; source-properties directly. +(define (annotation? x) #f) + +;; API provided by psyntax +(define syntax-violation #f) +(define datum->syntax #f) +(define syntax->datum #f) +(define identifier? #f) +(define generate-temporaries #f) +(define bound-identifier=? #f) +(define free-identifier=? #f) +(define sc-expand #f) + +;; $sc-expand is an implementation detail of psyntax. It is used by +;; expanded macros, to dispatch an input against a set of patterns. +(define $sc-dispatch #f) + +;; Load it up! +(primitive-load-path "ice-9/psyntax-pp") + +;; %pre-modules-transformer is the Scheme expander from now until the +;; module system has booted up. +(define %pre-modules-transformer sc-expand) + +(define-syntax and + (syntax-rules () + ((_) #t) + ((_ x) x) + ((_ x y ...) (if x (and y ...) #f)))) + +(define-syntax or + (syntax-rules () + ((_) #f) + ((_ x) x) + ((_ x y ...) (let ((t x)) (if t t (or y ...)))))) + +;; The "maybe-more" bits are something of a hack, so that we can support +;; SRFI-61. Rewrites into a standalone syntax-case macro would be +;; appreciated. +(define-syntax cond + (syntax-rules (=> else) + ((_ "maybe-more" test consequent) + (if test consequent)) + + ((_ "maybe-more" test consequent clause ...) + (if test consequent (cond clause ...))) + + ((_ (else else1 else2 ...)) + (begin else1 else2 ...)) + + ((_ (test => receiver) more-clause ...) + (let ((t test)) + (cond "maybe-more" t (receiver t) more-clause ...))) + + ((_ (generator guard => receiver) more-clause ...) + (call-with-values (lambda () generator) + (lambda t + (cond "maybe-more" + (apply guard t) (apply receiver t) more-clause ...)))) + + ((_ (test => receiver ...) more-clause ...) + (syntax-violation 'cond "wrong number of receiver expressions" + '(test => receiver ...))) + ((_ (generator guard => receiver ...) more-clause ...) + (syntax-violation 'cond "wrong number of receiver expressions" + '(generator guard => receiver ...))) + + ((_ (test) more-clause ...) + (let ((t test)) + (cond "maybe-more" t t more-clause ...))) + + ((_ (test body1 body2 ...) more-clause ...) + (cond "maybe-more" + test (begin body1 body2 ...) more-clause ...)))) + +(define-syntax case + (syntax-rules (else) + ((case (key ...) + clauses ...) + (let ((atom-key (key ...))) + (case atom-key clauses ...))) + ((case key + (else result1 result2 ...)) + (begin result1 result2 ...)) + ((case key + ((atoms ...) result1 result2 ...)) + (if (memv key '(atoms ...)) + (begin result1 result2 ...))) + ((case key + ((atoms ...) result1 result2 ...) + clause clauses ...) + (if (memv key '(atoms ...)) + (begin result1 result2 ...) + (case key clause clauses ...))))) + +(define-syntax do + (syntax-rules () + ((do ((var init step ...) ...) + (test expr ...) + command ...) + (letrec + ((loop + (lambda (var ...) + (if test + (begin + (if #f #f) + expr ...) + (begin + command + ... + (loop (do "step" var step ...) + ...)))))) + (loop init ...))) + ((do "step" x) + x) + ((do "step" x y) + y))) + +(define-syntax delay + (syntax-rules () + ((_ exp) (make-promise (lambda () exp))))) + + + +;;; {Defmacros} +;;; + +(define-syntax define-macro + (lambda (x) + "Define a defmacro." + (syntax-case x () + ((_ (macro . args) doc body1 body ...) + (string? (syntax->datum (syntax doc))) + (syntax (define-macro macro doc (lambda args body1 body ...)))) + ((_ (macro . args) body ...) + (syntax (define-macro macro #f (lambda args body ...)))) + ((_ macro doc transformer) + (or (string? (syntax->datum (syntax doc))) + (not (syntax->datum (syntax doc)))) + (syntax + (define-syntax macro + (lambda (y) + doc + (syntax-case y () + ((_ . args) + (let ((v (syntax->datum (syntax args)))) + (datum->syntax y (apply transformer v)))))))))))) + +(define-syntax defmacro + (lambda (x) + "Define a defmacro, with the old lispy defun syntax." + (syntax-case x () + ((_ macro args doc body1 body ...) + (string? (syntax->datum (syntax doc))) + (syntax (define-macro macro doc (lambda args body1 body ...)))) + ((_ macro args body ...) + (syntax (define-macro macro #f (lambda args body ...))))))) + +(provide 'defmacro) + + + +;;; {Deprecation} +;;; +;;; Depends on: defmacro +;;; + +(defmacro begin-deprecated forms + (if (include-deprecated-features) + `(begin ,@forms) + `(begin))) + + + ;;; {Trivial Functions} ;;; @@ -250,8 +382,12 @@ (define (apply-to-args args fn) (apply fn args)) (defmacro false-if-exception (expr) - `(catch #t (lambda () ,expr) - (lambda args #f))) + `(catch #t + (lambda () + ;; avoid saving backtraces inside false-if-exception + (with-fluid* the-last-stack (fluid-ref the-last-stack) + (lambda () ,expr))) + (lambda args #f))) @@ -472,40 +608,6 @@ -;;; {and-map and or-map} -;;; -;;; (and-map fn lst) is like (and (fn (car lst)) (fn (cadr lst)) (fn...) ...) -;;; (or-map fn lst) is like (or (fn (car lst)) (fn (cadr lst)) (fn...) ...) -;;; - -;; and-map f l -;; -;; Apply f to successive elements of l until exhaustion or f returns #f. -;; If returning early, return #f. Otherwise, return the last value returned -;; by f. If f has never been called because l is empty, return #t. -;; -(define (and-map f lst) - (let loop ((result #t) - (l lst)) - (and result - (or (and (null? l) - result) - (loop (f (car l)) (cdr l)))))) - -;; or-map f l -;; -;; Apply f to successive elements of l until exhaustion or while f returns #f. -;; If returning early, return the return value of f. -;; -(define (or-map f lst) - (let loop ((result #f) - (l lst)) - (or result - (and (not (null? l)) - (loop (f (car l)) (cdr l)))))) - - - (if (provided? 'posix) (primitive-load-path "ice-9/posix")) @@ -513,12 +615,10 @@ (primitive-load-path "ice-9/networking")) ;; For reference, Emacs file-exists-p uses stat in this same way. -;; ENHANCE-ME: Catching an exception from stat is a bit wasteful, do this in -;; C where all that's needed is to inspect the return from stat(). (define file-exists? (if (provided? 'posix) (lambda (str) - (->bool (false-if-exception (stat str)))) + (->bool (stat str #f))) (lambda (str) (let ((port (catch 'system-error (lambda () (open-file str OPEN_READ)) (lambda args #f)))) @@ -752,6 +852,26 @@ (start-stack 'load-stack (primitive-load-path name))) +(define %load-verbosely #f) +(define (assert-load-verbosity v) (set! %load-verbosely v)) + +(define (%load-announce file) + (if %load-verbosely + (with-output-to-port (current-error-port) + (lambda () + (display ";;; ") + (display "loading ") + (display file) + (newline) + (force-output))))) + +(set! %load-hook %load-announce) + +(define (load name . reader) + (with-fluid* current-reader (and (pair? reader) (car reader)) + (lambda () + (start-stack 'load-stack + (primitive-load name))))) @@ -843,9 +963,6 @@ ;;; Reader code for various "#c" forms. ;;; -(read-hash-extend #\' (lambda (c port) - (read port))) - (define read-eval? (make-fluid)) (fluid-set! read-eval? #f) (read-hash-extend #\. @@ -1128,11 +1245,8 @@ (define (%print-module mod port) ; unused args: depth length style table) (display "#<" port) (display (or (module-kind mod) "module") port) - (let ((name (module-name mod))) - (if name - (begin - (display " " port) - (display name port)))) + (display " " port) + (display (module-name mod) port) (display " " port) (display (number->string (object-address mod) 16) port) (display ">" port)) @@ -1189,7 +1303,8 @@ "Lazy-binder expected to be a procedure or #f." binder)) (let ((module (module-constructor (make-hash-table size) - uses binder #f #f #f #f #f + uses binder #f %pre-modules-transformer + #f #f #f (make-hash-table %default-import-size) '() (make-weak-key-hash-table 31)))) @@ -1214,7 +1329,7 @@ (define module-transformer (record-accessor module-type 'transformer)) (define set-module-transformer! (record-modifier module-type 'transformer)) -(define module-name (record-accessor module-type 'name)) +;; (define module-name (record-accessor module-type 'name)) wait until mods are booted (define set-module-name! (record-modifier module-type 'name)) (define module-kind (record-accessor module-type 'kind)) (define set-module-kind! (record-modifier module-type 'kind)) @@ -1368,7 +1483,9 @@ ;; or its uses? ;; (define (module-bound? m v) - (module-search module-locally-bound? m v)) + (let ((var (module-variable m v))) + (and var + (variable-bound? var)))) ;;; {Is a symbol interned in a module?} ;;; @@ -1804,7 +1921,7 @@ val (let ((m (make-module 31))) (set-module-kind! m 'directory) - (set-module-name! m (append (or (module-name module) '()) + (set-module-name! m (append (module-name module) (list (car name)))) (module-define! module (car name) m) m))) @@ -1858,22 +1975,36 @@ (define default-duplicate-binding-procedures #f) (define %app (make-module 31)) +(set-module-name! %app '(%app)) (define app %app) ;; for backwards compatability -(local-define '(%app modules) (make-module 31)) +(let ((m (make-module 31))) + (set-module-name! m '()) + (local-define '(%app modules) m)) (local-define '(%app modules guile) the-root-module) ;; This boots the module system. All bindings needed by modules.c ;; must have been defined by now. ;; (set-current-module the-root-module) +;; definition deferred for syncase's benefit. +(define module-name + (let ((accessor (record-accessor module-type 'name))) + (lambda (mod) + (or (accessor mod) + (let ((name (list (gensym)))) + ;; Name MOD and bind it in THE-ROOT-MODULE so that it's visible + ;; to `resolve-module'. This is important as `psyntax' stores + ;; module names and relies on being able to `resolve-module' + ;; them. + (set-module-name! mod name) + (nested-define! the-root-module `(%app modules ,@name) mod) + (accessor mod)))))) ;; (define-special-value '(%app modules new-ws) (lambda () (make-scm-module))) (define (try-load-module name) - (or (begin-deprecated (try-module-linked name)) - (try-module-autoload name) - (begin-deprecated (try-module-dynamic-link name)))) + (try-module-autoload name)) (define (purify-module! module) "Removes bindings in MODULE which are inherited from the (guile) module." @@ -2007,23 +2138,34 @@ ((#:use-module #:use-syntax) (or (pair? (cdr kws)) (unrecognized kws)) - (let* ((interface-args (cadr kws)) - (interface (apply resolve-interface interface-args))) - (and (eq? (car kws) #:use-syntax) - (or (symbol? (caar interface-args)) - (error "invalid module name for use-syntax" - (car interface-args))) - (set-module-transformer! - module - (module-ref interface - (car (last-pair (car interface-args))) - #f))) + (cond + ((equal? (caadr kws) '(ice-9 syncase)) + (issue-deprecation-warning + "(ice-9 syncase) is deprecated. Support for syntax-case is now in Guile core.") (loop (cddr kws) - (cons interface reversed-interfaces) + reversed-interfaces exports re-exports replacements - autoloads))) + autoloads)) + (else + (let* ((interface-args (cadr kws)) + (interface (apply resolve-interface interface-args))) + (and (eq? (car kws) #:use-syntax) + (or (symbol? (caar interface-args)) + (error "invalid module name for use-syntax" + (car interface-args))) + (set-module-transformer! + module + (module-ref interface + (car (last-pair (car interface-args))) + #f))) + (loop (cddr kws) + (cons interface reversed-interfaces) + exports + re-exports + replacements + autoloads))))) ((#:autoload) (or (and (pair? (cdr kws)) (pair? (cddr kws))) (unrecognized kws)) @@ -2126,11 +2268,6 @@ module '(ice-9 q) '(make-q q-length))}." (loop (cddr args))))))) -;;; {Compiled module} - -(if (not (defined? 'load-compiled)) - (define load-compiled #f)) - ;;; {Autoloading modules} @@ -2152,27 +2289,15 @@ module '(ice-9 q) '(make-q q-length))}." (resolve-module dir-hint-module-name #f) (and (not (autoload-done-or-in-progress? dir-hint name)) (let ((didit #f)) - (define (load-file proc file) - (save-module-excursion (lambda () (proc file))) - (set! didit #t)) (dynamic-wind (lambda () (autoload-in-progress! dir-hint name)) (lambda () - (let ((file (in-vicinity dir-hint name))) - (let ((compiled (and load-compiled - (%search-load-path - (string-append file ".go")))) - (source (%search-load-path file))) - (cond ((and source - (or (not compiled) - (< (stat:mtime (stat compiled)) - (stat:mtime (stat source))))) - (if compiled - (warn "source file" source "newer than" compiled)) - (with-fluids ((current-reader #f)) - (load-file primitive-load source))) - (compiled - (load-file load-compiled compiled)))))) + (with-fluid* current-reader #f + (lambda () + (save-module-excursion + (lambda () + (primitive-load-path (in-vicinity dir-hint name) #f) + (set! didit #t)))))) (lambda () (set-autoloaded! dir-hint name didit))) didit)))) @@ -2214,9 +2339,9 @@ module '(ice-9 q) '(make-q q-length))}." ;;; (defmacro define-option-interface (option-group) - (let* ((option-name car) - (option-value cadr) - (option-documentation caddr) + (let* ((option-name 'car) + (option-value 'cadr) + (option-documentation 'caddr) ;; Below follow the macros defining the run-time option interfaces. @@ -2227,15 +2352,15 @@ module '(ice-9 q) '(make-q q-length))}." (,interface (car args)) (,interface)) (else (for-each (lambda (option) - (display (option-name option)) + (display (,option-name option)) (if (< (string-length - (symbol->string (option-name option))) + (symbol->string (,option-name option))) 8) (display #\tab)) (display #\tab) - (display (option-value option)) + (display (,option-value option)) (display #\tab) - (display (option-documentation option)) + (display (,option-documentation option)) (newline)) (,interface #t))))))) @@ -2320,11 +2445,12 @@ module '(ice-9 q) '(make-q q-length))}." (define (set-repl-prompt! v) (set! scm-repl-prompt v)) (define (default-pre-unwind-handler key . args) - (save-stack pre-unwind-handler-dispatch) + (save-stack 1) (apply throw key args)) -(define (pre-unwind-handler-dispatch key . args) - (apply default-pre-unwind-handler key args)) +(begin-deprecated + (define (pre-unwind-handler-dispatch key . args) + (apply default-pre-unwind-handler key args))) (define abort-hook (make-hook)) @@ -2401,15 +2527,7 @@ module '(ice-9 q) '(make-q q-length))}." (else (apply bad-throw key args))))))) - ;; Note that having just `pre-unwind-handler-dispatch' - ;; here is connected with the mechanism that - ;; produces a nice backtrace upon error. If, for - ;; example, this is replaced with (lambda args - ;; (apply pre-unwind-handler-dispatch args)), the stack - ;; cutting (in save-stack) goes wrong and ends up - ;; saving no stack at all, so there is no - ;; backtrace. - pre-unwind-handler-dispatch))) + default-pre-unwind-handler))) (if next (loop next) status))) (set! set-batch-mode?! (lambda (arg) @@ -2684,32 +2802,6 @@ module '(ice-9 q) '(make-q q-length))}." `(with-fluids* (list ,@fluids) (list ,@values) (lambda () ,@body))))) - - -;;; {Macros} -;;; - -;; actually....hobbit might be able to hack these with a little -;; coaxing -;; - -(define (primitive-macro? m) - (and (macro? m) - (not (macro-transformer m)))) - -(defmacro define-macro (first . rest) - (let ((name (if (symbol? first) first (car first))) - (transformer - (if (symbol? first) - (car rest) - `(lambda ,(cdr first) ,@rest)))) - `(eval-when - (eval load compile) - (define ,name (defmacro:transformer ,transformer))))) - - - - ;;; {While} ;;; ;;; with `continue' and `break'. @@ -2849,50 +2941,31 @@ module '(ice-9 q) '(make-q q-length))}." (defmacro use-syntax (spec) `(eval-when (eval load compile) - ,@(if (pair? spec) - `((process-use-modules (list - (list ,@(compile-interface-spec spec)))) - (set-module-transformer! (current-module) - ,(car (last-pair spec)))) - `((set-module-transformer! (current-module) ,spec))) - *unspecified*)) + (issue-deprecation-warning + "`use-syntax' is deprecated. Please contact guile-devel for more info.") + (process-use-modules (list (list ,@(compile-interface-spec spec)))) + *unspecified*)) -;; Dirk:FIXME:: This incorrect (according to R5RS) syntax needs to be changed -;; as soon as guile supports hygienic macros. -(define define-private define) +(define-syntax define-private + (syntax-rules () + ((_ foo bar) + (define foo bar)))) -(defmacro define-public args - (define (syntax) - (error "bad syntax" (list 'define-public args))) - (define (defined-name n) - (cond - ((symbol? n) n) - ((pair? n) (defined-name (car n))) - (else (syntax)))) - (cond - ((null? args) - (syntax)) - (#t - (let ((name (defined-name (car args)))) - `(begin - (define-private ,@args) - (export ,name)))))) +(define-syntax define-public + (syntax-rules () + ((_ (name . args) . body) + (define-public name (lambda args . body))) + ((_ name val) + (begin + (define name val) + (export name))))) -(defmacro defmacro-public args - (define (syntax) - (error "bad syntax" (list 'defmacro-public args))) - (define (defined-name n) - (cond - ((symbol? n) n) - (else (syntax)))) - (cond - ((null? args) - (syntax)) - (#t - (let ((name (defined-name (car args)))) - `(begin - (export-syntax ,name) - (defmacro ,@args)))))) +(define-syntax defmacro-public + (syntax-rules () + ((_ name args . body) + (begin + (defmacro name args . body) + (export-syntax name))))) ;; Export a local variable @@ -2946,44 +3019,6 @@ module '(ice-9 q) '(make-q q-length))}." (define load load-module) -;; The following macro allows one to write, for example, -;; -;; (@ (ice-9 pretty-print) pretty-print) -;; -;; to refer directly to the pretty-print variable in module (ice-9 -;; pretty-print). It works by looking up the variable and inserting -;; it directly into the code. This is understood by the evaluator. -;; Indeed, all references to global variables are memoized into such -;; variable objects. - -(define-macro (@ mod-name var-name) - (let ((var (module-variable (resolve-interface mod-name) var-name))) - (if (not var) - (error "no such public variable" (list '@ mod-name var-name))) - var)) - -;; The '@@' macro is like '@' but it can also access bindings that -;; have not been explicitely exported. - -(define-macro (@@ mod-name var-name) - (let ((var (module-variable (resolve-module mod-name) var-name))) - (if (not var) - (error "no such variable" (list '@@ mod-name var-name))) - var)) - - - -;;; {Compiler interface} -;;; -;;; The full compiler interface can be found in (system). Here we put a -;;; few useful procedures into the global namespace. - -(module-autoload! the-scm-module - '(system base compile) - '(compile - compile-time-environment)) - - ;;; {Parameters} @@ -3172,69 +3207,66 @@ module '(ice-9 q) '(make-q q-length))}." (append (hashq-ref %cond-expand-table mod '()) features))))) -(define cond-expand - (procedure->memoizing-macro - (lambda (exp env) - (let ((clauses (cdr exp)) - (syntax-error (lambda (cl) - (error "invalid clause in `cond-expand'" cl)))) - (letrec - ((test-clause - (lambda (clause) - (cond - ((symbol? clause) - (or (memq clause %cond-expand-features) - (let lp ((uses (module-uses (env-module env)))) - (if (pair? uses) - (or (memq clause - (hashq-ref %cond-expand-table - (car uses) '())) - (lp (cdr uses))) - #f)))) - ((pair? clause) - (cond - ((eq? 'and (car clause)) - (let lp ((l (cdr clause))) - (cond ((null? l) - #t) - ((pair? l) - (and (test-clause (car l)) (lp (cdr l)))) - (else - (syntax-error clause))))) - ((eq? 'or (car clause)) - (let lp ((l (cdr clause))) - (cond ((null? l) - #f) - ((pair? l) - (or (test-clause (car l)) (lp (cdr l)))) - (else - (syntax-error clause))))) - ((eq? 'not (car clause)) - (cond ((not (pair? (cdr clause))) - (syntax-error clause)) - ((pair? (cddr clause)) - ((syntax-error clause)))) - (not (test-clause (cadr clause)))) - (else - (syntax-error clause)))) - (else - (syntax-error clause)))))) - (let lp ((c clauses)) - (cond - ((null? c) - (error "Unfulfilled `cond-expand'")) - ((not (pair? c)) - (syntax-error c)) - ((not (pair? (car c))) - (syntax-error (car c))) - ((test-clause (caar c)) - `(begin ,@(cdar c))) - ((eq? (caar c) 'else) - (if (pair? (cdr c)) - (syntax-error c)) - `(begin ,@(cdar c))) - (else - (lp (cdr c)))))))))) +(define-macro (cond-expand . clauses) + (let ((syntax-error (lambda (cl) + (error "invalid clause in `cond-expand'" cl)))) + (letrec + ((test-clause + (lambda (clause) + (cond + ((symbol? clause) + (or (memq clause %cond-expand-features) + (let lp ((uses (module-uses (current-module)))) + (if (pair? uses) + (or (memq clause + (hashq-ref %cond-expand-table + (car uses) '())) + (lp (cdr uses))) + #f)))) + ((pair? clause) + (cond + ((eq? 'and (car clause)) + (let lp ((l (cdr clause))) + (cond ((null? l) + #t) + ((pair? l) + (and (test-clause (car l)) (lp (cdr l)))) + (else + (syntax-error clause))))) + ((eq? 'or (car clause)) + (let lp ((l (cdr clause))) + (cond ((null? l) + #f) + ((pair? l) + (or (test-clause (car l)) (lp (cdr l)))) + (else + (syntax-error clause))))) + ((eq? 'not (car clause)) + (cond ((not (pair? (cdr clause))) + (syntax-error clause)) + ((pair? (cddr clause)) + ((syntax-error clause)))) + (not (test-clause (cadr clause)))) + (else + (syntax-error clause)))) + (else + (syntax-error clause)))))) + (let lp ((c clauses)) + (cond + ((null? c) + (error "Unfulfilled `cond-expand'")) + ((not (pair? c)) + (syntax-error c)) + ((not (pair? (car c))) + (syntax-error (car c))) + ((test-clause (caar c)) + `(begin ,@(cdar c))) + ((eq? (caar c) 'else) + (if (pair? (cdr c)) + (syntax-error c)) + `(begin ,@(cdar c))) + (else + (lp (cdr c)))))))) ;; This procedure gets called from the startup code with a list of ;; numbers, which are the numbers of the SRFIs to be loaded on startup. @@ -3406,6 +3438,13 @@ module '(ice-9 q) '(make-q q-length))}." ;;; Place the user in the guile-user module. ;;; -(define-module (guile-user)) +;;; FIXME: annotate ? +;; (define (syncase exp) +;; (with-fluids ((expansion-eval-closure +;; (module-eval-closure (current-module)))) +;; (deannotate/source-properties (sc-expand (annotate exp))))) + +(define-module (guile-user) + #:autoload (system base compile) (compile)) ;;; boot-9.scm ends here diff --git a/module/ice-9/buffered-input.scm b/module/ice-9/buffered-input.scm index 11530e897..05e9255c0 100644 --- a/module/ice-9/buffered-input.scm +++ b/module/ice-9/buffered-input.scm @@ -5,7 +5,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/module/ice-9/calling.scm b/module/ice-9/calling.scm index 07f7a7805..f66bba27e 100644 --- a/module/ice-9/calling.scm +++ b/module/ice-9/calling.scm @@ -5,7 +5,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/module/ice-9/channel.scm b/module/ice-9/channel.scm index 8cbb00190..b9d470044 100644 --- a/module/ice-9/channel.scm +++ b/module/ice-9/channel.scm @@ -2,19 +2,19 @@ ;; Copyright (C) 2001, 2006 Free Software Foundation, Inc. -;; This library is free software; you can redistribute it and/or -;; modify it under the terms of the GNU Lesser General Public -;; License as published by the Free Software Foundation; either -;; version 2.1 of the License, or (at your option) any later version. -;; -;; This library is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;; Lesser General Public License for more details. -;; -;; You should have received a copy of the GNU Lesser General Public -;; License along with this library; if not, write to the Free Software -;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Commentary: diff --git a/module/ice-9/common-list.scm b/module/ice-9/common-list.scm index 7d62bc319..ea1b0f3de 100644 --- a/module/ice-9/common-list.scm +++ b/module/ice-9/common-list.scm @@ -5,7 +5,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/module/ice-9/compile-psyntax.scm b/module/ice-9/compile-psyntax.scm index a2fe77546..8b53267fe 100644 --- a/module/ice-9/compile-psyntax.scm +++ b/module/ice-9/compile-psyntax.scm @@ -1,27 +1,20 @@ -(use-modules (ice-9 syncase)) - -;; XXX - We need to be inside (ice-9 syncase) since psyntax.ss calls -;; `eval' int he `interaction-environment' aka the current module and -;; it expects to have `andmap' there. The reason for this escapes me -;; at the moment. -;; -(define-module (ice-9 syncase)) - -(define source (list-ref (command-line) 1)) -(define target (list-ref (command-line) 2)) - -(let ((in (open-input-file source)) - (out (open-output-file (string-append target ".tmp")))) - (with-fluids ((expansion-eval-closure - (module-eval-closure (current-module)))) +(use-modules (language tree-il) (ice-9 pretty-print)) +(let ((source (list-ref (command-line) 1)) + (target (list-ref (command-line) 2))) + (let ((in (open-input-file source)) + (out (open-output-file (string-append target ".tmp")))) + (write '(eval-when (compile) (set-current-module (resolve-module '(guile)))) + out) + (newline out) (let loop ((x (read in))) (if (eof-object? x) - (begin - (close-port out) - (close-port in)) - (begin - (write (sc-expand3 x 'c '(compile load eval)) out) - (newline out) - (loop (read in))))))) - -(system (format #f "mv -f ~s.tmp ~s" target target)) + (begin + (close-port out) + (close-port in)) + (begin + (pretty-print (tree-il->scheme + (sc-expand x 'c '(compile load eval))) + out) + (newline out) + (loop (read in)))))) + (system (format #f "mv -f ~s.tmp ~s" target target))) diff --git a/module/ice-9/debug.scm b/module/ice-9/debug.scm index 0e751590d..1fd5b66da 100644 --- a/module/ice-9/debug.scm +++ b/module/ice-9/debug.scm @@ -3,7 +3,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/module/ice-9/debugger.scm b/module/ice-9/debugger.scm index 3dddd9030..06f7ed230 100644 --- a/module/ice-9/debugger.scm +++ b/module/ice-9/debugger.scm @@ -2,19 +2,19 @@ ;;; Copyright (C) 1999, 2001, 2002, 2006 Free Software Foundation, Inc. ;;; -;; This library is free software; you can redistribute it and/or -;; modify it under the terms of the GNU Lesser General Public -;; License as published by the Free Software Foundation; either -;; version 2.1 of the License, or (at your option) any later version. -;; -;; This library is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;; Lesser General Public License for more details. -;; -;; You should have received a copy of the GNU Lesser General Public -;; License along with this library; if not, write to the Free Software -;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (define-module (ice-9 debugger) #:use-module (ice-9 debugger command-loop) diff --git a/module/ice-9/debugger/Makefile.am b/module/ice-9/debugger/Makefile.am deleted file mode 100644 index 7ef09a025..000000000 --- a/module/ice-9/debugger/Makefile.am +++ /dev/null @@ -1,31 +0,0 @@ -## Process this file with automake to produce Makefile.in. -## -## Copyright (C) 2002, 2004, 2006 Free Software Foundation, Inc. -## -## This file is part of GUILE. -## -## GUILE 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, or -## (at your option) any later version. -## -## GUILE 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 GUILE; see the file COPYING. If not, write -## to the Free Software Foundation, Inc., 51 Franklin Street, Fifth -## Floor, Boston, MA 02110-1301 USA - -AUTOMAKE_OPTIONS = gnu - -# These should be installed and distributed. -ice9_debugger_sources = command-loop.scm commands.scm state.scm trc.scm utils.scm - -subpkgdatadir = $(pkgdatadir)/$(GUILE_EFFECTIVE_VERSION)/ice-9/debugger -subpkgdata_DATA = $(ice9_debugger_sources) -TAGS_FILES = $(subpkgdata_DATA) - -EXTRA_DIST = $(ice9_debugger_sources) diff --git a/module/ice-9/debugger/command-loop.scm b/module/ice-9/debugger/command-loop.scm index 62a08ea65..c6628271c 100644 --- a/module/ice-9/debugger/command-loop.scm +++ b/module/ice-9/debugger/command-loop.scm @@ -2,19 +2,19 @@ ;;; Copyright (C) 1999, 2001, 2002, 2003, 2006 Free Software Foundation, Inc. ;;; -;; This library is free software; you can redistribute it and/or -;; modify it under the terms of the GNU Lesser General Public -;; License as published by the Free Software Foundation; either -;; version 2.1 of the License, or (at your option) any later version. -;; -;; This library is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;; Lesser General Public License for more details. -;; -;; You should have received a copy of the GNU Lesser General Public -;; License along with this library; if not, write to the Free Software -;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (define-module (ice-9 debugger command-loop) #:use-module ((ice-9 debugger commands) :prefix debugger:) diff --git a/module/ice-9/debugger/commands.scm b/module/ice-9/debugger/commands.scm index ef6f79026..c254ce9e2 100644 --- a/module/ice-9/debugger/commands.scm +++ b/module/ice-9/debugger/commands.scm @@ -2,19 +2,19 @@ ;;; Copyright (C) 2002, 2006 Free Software Foundation, Inc. ;;; -;; This library is free software; you can redistribute it and/or -;; modify it under the terms of the GNU Lesser General Public -;; License as published by the Free Software Foundation; either -;; version 2.1 of the License, or (at your option) any later version. -;; -;; This library is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;; Lesser General Public License for more details. -;; -;; You should have received a copy of the GNU Lesser General Public -;; License along with this library; if not, write to the Free Software -;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (define-module (ice-9 debugger commands) #:use-module (ice-9 debug) diff --git a/module/ice-9/debugger/state.scm b/module/ice-9/debugger/state.scm index 11b8ebbf0..0bda0fad5 100644 --- a/module/ice-9/debugger/state.scm +++ b/module/ice-9/debugger/state.scm @@ -2,19 +2,19 @@ ;;; Copyright (C) 2002, 2006 Free Software Foundation, Inc. ;;; -;; This library is free software; you can redistribute it and/or -;; modify it under the terms of the GNU Lesser General Public -;; License as published by the Free Software Foundation; either -;; version 2.1 of the License, or (at your option) any later version. -;; -;; This library is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;; Lesser General Public License for more details. -;; -;; You should have received a copy of the GNU Lesser General Public -;; License along with this library; if not, write to the Free Software -;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (define-module (ice-9 debugger state) #:export (make-state diff --git a/module/ice-9/debugger/trc.scm b/module/ice-9/debugger/trc.scm index 49af2747d..3e7e2f359 100644 --- a/module/ice-9/debugger/trc.scm +++ b/module/ice-9/debugger/trc.scm @@ -2,19 +2,19 @@ ;;; Copyright (C) 2002, 2006 Free Software Foundation, Inc. ;;; -;; This library is free software; you can redistribute it and/or -;; modify it under the terms of the GNU Lesser General Public -;; License as published by the Free Software Foundation; either -;; version 2.1 of the License, or (at your option) any later version. -;; -;; This library is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;; Lesser General Public License for more details. -;; -;; You should have received a copy of the GNU Lesser General Public -;; License along with this library; if not, write to the Free Software -;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (define-module (ice-9 debugger trc) #:export (trc trc-syms trc-all trc-none trc-add trc-remove trc-port)) diff --git a/module/ice-9/debugging/Makefile.am b/module/ice-9/debugging/Makefile.am deleted file mode 100644 index 44d86d3cf..000000000 --- a/module/ice-9/debugging/Makefile.am +++ /dev/null @@ -1,33 +0,0 @@ -## Process this file with automake to produce Makefile.in. -## -## Copyright (C) 2006 Free Software Foundation, Inc. -## -## This file is part of GUILE. -## -## GUILE 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, or -## (at your option) any later version. -## -## GUILE 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 GUILE; see the file COPYING. If not, write -## to the Free Software Foundation, Inc., 51 Franklin Street, Fifth -## Floor, Boston, MA 02110-1301 USA - -AUTOMAKE_OPTIONS = gnu - -# These should be installed and distributed. -ice9_debugging_sources = example-fns.scm \ - ice-9-debugger-extensions.scm \ - steps.scm trace.scm traps.scm trc.scm - -subpkgdatadir = $(pkgdatadir)/${GUILE_EFFECTIVE_VERSION}/ice-9/debugging -subpkgdata_DATA = $(ice9_debugging_sources) -TAGS_FILES = $(subpkgdata_DATA) - -EXTRA_DIST = $(ice9_debugging_sources) diff --git a/module/ice-9/debugging/breakpoints.scm b/module/ice-9/debugging/breakpoints.scm index 132746f17..c839409ef 100644 --- a/module/ice-9/debugging/breakpoints.scm +++ b/module/ice-9/debugging/breakpoints.scm @@ -2,19 +2,19 @@ ;;; Copyright (C) 2005 Neil Jerram ;;; -;; This library is free software; you can redistribute it and/or -;; modify it under the terms of the GNU Lesser General Public -;; License as published by the Free Software Foundation; either -;; version 2.1 of the License, or (at your option) any later version. -;; -;; This library is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;; Lesser General Public License for more details. -;; -;; You should have received a copy of the GNU Lesser General Public -;; License along with this library; if not, write to the Free Software -;; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; This module provides a practical interface for setting and ;;; manipulating breakpoints. diff --git a/module/ice-9/debugging/steps.scm b/module/ice-9/debugging/steps.scm index fedbc6a32..cd328bd7d 100644 --- a/module/ice-9/debugging/steps.scm +++ b/module/ice-9/debugging/steps.scm @@ -2,19 +2,19 @@ ;;; Copyright (C) 2002, 2004 Free Software Foundation, Inc. ;;; -;; This library is free software; you can redistribute it and/or -;; modify it under the terms of the GNU Lesser General Public -;; License as published by the Free Software Foundation; either -;; version 2.1 of the License, or (at your option) any later version. -;; -;; This library is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;; Lesser General Public License for more details. -;; -;; You should have received a copy of the GNU Lesser General Public -;; License along with this library; if not, write to the Free Software -;; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (define-module (ice-9 debugging steps) #:use-module (ice-9 debugging traps) diff --git a/module/ice-9/debugging/trace.scm b/module/ice-9/debugging/trace.scm index ad3015ddf..55b1f3965 100644 --- a/module/ice-9/debugging/trace.scm +++ b/module/ice-9/debugging/trace.scm @@ -2,19 +2,19 @@ ;;; Copyright (C) 2002 Free Software Foundation, Inc. ;;; -;; This library is free software; you can redistribute it and/or -;; modify it under the terms of the GNU Lesser General Public -;; License as published by the Free Software Foundation; either -;; version 2.1 of the License, or (at your option) any later version. -;; -;; This library is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;; Lesser General Public License for more details. -;; -;; You should have received a copy of the GNU Lesser General Public -;; License along with this library; if not, write to the Free Software -;; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (define-module (ice-9 debugging trace) #:use-module (ice-9 debug) diff --git a/module/ice-9/debugging/traps.scm b/module/ice-9/debugging/traps.scm index ae1673688..e13011e99 100755 --- a/module/ice-9/debugging/traps.scm +++ b/module/ice-9/debugging/traps.scm @@ -3,19 +3,19 @@ ;;; Copyright (C) 2002, 2004 Free Software Foundation, Inc. ;;; Copyright (C) 2005 Neil Jerram ;;; -;; This library is free software; you can redistribute it and/or -;; modify it under the terms of the GNU Lesser General Public -;; License as published by the Free Software Foundation; either -;; version 2.1 of the License, or (at your option) any later version. -;; -;; This library is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;; Lesser General Public License for more details. -;; -;; You should have received a copy of the GNU Lesser General Public -;; License along with this library; if not, write to the Free Software -;; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; This module provides an abstraction around Guile's low level trap ;;; handler interface; its aim is to make the low level trap mechanism diff --git a/module/ice-9/debugging/trc.scm b/module/ice-9/debugging/trc.scm index 9e95d7e5c..face227d6 100644 --- a/module/ice-9/debugging/trc.scm +++ b/module/ice-9/debugging/trc.scm @@ -2,19 +2,19 @@ ;;; Copyright (C) 2002, 2004 Free Software Foundation, Inc. ;;; -;; This library is free software; you can redistribute it and/or -;; modify it under the terms of the GNU Lesser General Public -;; License as published by the Free Software Foundation; either -;; version 2.1 of the License, or (at your option) any later version. -;; -;; This library is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;; Lesser General Public License for more details. -;; -;; You should have received a copy of the GNU Lesser General Public -;; License along with this library; if not, write to the Free Software -;; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (define-module (ice-9 debugging trc) #:export (trc trc-syms trc-all trc-none trc-add trc-remove trc-port)) diff --git a/module/ice-9/deprecated.scm b/module/ice-9/deprecated.scm index f3b7cafe4..53fc741c8 100644 --- a/module/ice-9/deprecated.scm +++ b/module/ice-9/deprecated.scm @@ -3,7 +3,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -21,7 +21,7 @@ (define substring-move-right! substring-move!) ;; This method of dynamically linking Guile Extensions is deprecated. -;; Use `load-extension' explicitely from Scheme code instead. +;; Use `load-extension' explicitly from Scheme code instead. (define (split-c-module-name str) (let loop ((rev '()) diff --git a/module/ice-9/documentation.scm b/module/ice-9/documentation.scm index c5f447e78..bbd6713f6 100644 --- a/module/ice-9/documentation.scm +++ b/module/ice-9/documentation.scm @@ -3,7 +3,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -195,15 +195,11 @@ OBJECT can be a procedure, macro or any object that has its `documentation' property set." (or (and (procedure? object) (proc-doc object)) - (and (defmacro? object) - (proc-doc (defmacro-transformer object))) - (and (macro? object) - (let ((transformer (macro-transformer object))) - (and transformer - (proc-doc transformer)))) (object-property object 'documentation) (and (program? object) (program-documentation object)) + (and (macro? object) + (object-documentation (macro-transformer object))) (and (procedure? object) (not (closure? object)) (procedure-name object) diff --git a/module/ice-9/emacs.scm b/module/ice-9/emacs.scm index 12d8228ee..88035862f 100644 --- a/module/ice-9/emacs.scm +++ b/module/ice-9/emacs.scm @@ -3,7 +3,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/module/ice-9/expect.scm b/module/ice-9/expect.scm index a024e91e8..ffc2e1742 100644 --- a/module/ice-9/expect.scm +++ b/module/ice-9/expect.scm @@ -3,7 +3,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/module/ice-9/ftw.scm b/module/ice-9/ftw.scm index 23f341521..ce2fb165e 100644 --- a/module/ice-9/ftw.scm +++ b/module/ice-9/ftw.scm @@ -5,7 +5,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/module/ice-9/gap-buffer.scm b/module/ice-9/gap-buffer.scm index b6162e802..4533bb539 100644 --- a/module/ice-9/gap-buffer.scm +++ b/module/ice-9/gap-buffer.scm @@ -2,19 +2,19 @@ ;;; Copyright (C) 2002, 2003, 2006 Free Software Foundation, Inc. ;;; -;; This library is free software; you can redistribute it and/or -;; modify it under the terms of the GNU Lesser General Public -;; License as published by the Free Software Foundation; either -;; version 2.1 of the License, or (at your option) any later version. -;; -;; This library is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;; Lesser General Public License for more details. -;; -;; You should have received a copy of the GNU Lesser General Public -;; License along with this library; if not, write to the Free Software -;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; ;;; Author: Thien-Thi Nguyen diff --git a/module/ice-9/gds-server.scm b/module/ice-9/gds-server.scm index f59758729..b64e41161 100644 --- a/module/ice-9/gds-server.scm +++ b/module/ice-9/gds-server.scm @@ -2,19 +2,19 @@ ;;; Copyright (C) 2003 Free Software Foundation, Inc. ;;; -;; This library is free software; you can redistribute it and/or -;; modify it under the terms of the GNU Lesser General Public -;; License as published by the Free Software Foundation; either -;; version 2.1 of the License, or (at your option) any later version. -;; -;; This library is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;; Lesser General Public License for more details. -;; -;; You should have received a copy of the GNU Lesser General Public -;; License along with this library; if not, write to the Free Software -;; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (define-module (ice-9 gds-server) #:export (run-server)) diff --git a/module/ice-9/getopt-long.scm b/module/ice-9/getopt-long.scm index b16328ba8..891a2e3b3 100644 --- a/module/ice-9/getopt-long.scm +++ b/module/ice-9/getopt-long.scm @@ -1,18 +1,18 @@ ;;; Copyright (C) 1998, 2001, 2006, 2009 Free Software Foundation, Inc. ;;; -;; This library is free software; you can redistribute it and/or -;; modify it under the terms of the GNU Lesser General Public -;; License as published by the Free Software Foundation; either -;; version 2.1 of the License, or (at your option) any later version. -;; -;; This library is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;; Lesser General Public License for more details. -;; -;; You should have received a copy of the GNU Lesser General Public -;; License along with this library; if not, write to the Free Software -;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Author: Russ McManus (rewritten by Thien-Thi Nguyen) diff --git a/module/ice-9/hcons.scm b/module/ice-9/hcons.scm index 6323506d2..7275cf476 100644 --- a/module/ice-9/hcons.scm +++ b/module/ice-9/hcons.scm @@ -5,7 +5,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/module/ice-9/history.scm b/module/ice-9/history.scm index 921a25741..e9097c2cc 100644 --- a/module/ice-9/history.scm +++ b/module/ice-9/history.scm @@ -3,7 +3,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/module/ice-9/i18n.scm b/module/ice-9/i18n.scm index f33a9f258..dd14e6754 100644 --- a/module/ice-9/i18n.scm +++ b/module/ice-9/i18n.scm @@ -5,13 +5,13 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. -;;;; +;;;; version 3 of the License, or (at your option) any later version. +;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;;;; Lesser General Public License for more details. -;;;; +;;;; ;;;; You should have received a copy of the GNU Lesser General Public ;;;; License along with this library; if not, write to the Free Software ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA diff --git a/module/ice-9/lineio.scm b/module/ice-9/lineio.scm index f122268df..055eb6eb4 100644 --- a/module/ice-9/lineio.scm +++ b/module/ice-9/lineio.scm @@ -5,7 +5,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/module/ice-9/list.scm b/module/ice-9/list.scm index af83d1742..1b898a368 100644 --- a/module/ice-9/list.scm +++ b/module/ice-9/list.scm @@ -2,19 +2,19 @@ ;;; Copyright (C) 2003, 2006 Free Software Foundation, Inc. ;;; -;; This library is free software; you can redistribute it and/or -;; modify it under the terms of the GNU Lesser General Public -;; License as published by the Free Software Foundation; either -;; version 2.1 of the License, or (at your option) any later version. -;; -;; This library is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;; Lesser General Public License for more details. -;; -;; You should have received a copy of the GNU Lesser General Public -;; License along with this library; if not, write to the Free Software -;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (define-module (ice-9 list) :export (rassoc rassv rassq)) diff --git a/module/ice-9/ls.scm b/module/ice-9/ls.scm index e848be32a..f729d58ce 100644 --- a/module/ice-9/ls.scm +++ b/module/ice-9/ls.scm @@ -5,7 +5,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/module/ice-9/mapping.scm b/module/ice-9/mapping.scm index c4ef4fe99..2907a8d89 100644 --- a/module/ice-9/mapping.scm +++ b/module/ice-9/mapping.scm @@ -5,7 +5,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/module/ice-9/match.scm b/module/ice-9/match.scm index e6fe56063..d7589239e 100644 --- a/module/ice-9/match.scm +++ b/module/ice-9/match.scm @@ -5,7 +5,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -194,6 +194,6 @@ (define match:runtime-structures #f) (define match:set-runtime-structures (lambda (v) (set! match:runtime-structures v))) (define match:primitive-vector? vector?) -(defmacro defstruct args (let ((field? (lambda (x) (if (symbol? x) ((lambda () #t)) (if (and (pair? x) (symbol? (car x)) (pair? (cdr x)) (symbol? (cadr x)) (null? (cddr x))) ((lambda () #t)) ((lambda () #f)))))) (selector-name (lambda (x) (if (symbol? x) ((lambda () x)) (if (and (pair? x) (symbol? (car x)) (pair? (cdr x)) (null? (cddr x))) ((lambda (s) s) (car x)) (match:error x))))) (mutator-name (lambda (x) (if (symbol? x) ((lambda () #f)) (if (and (pair? x) (pair? (cdr x)) (symbol? (cadr x)) (null? (cddr x))) ((lambda (s) s) (cadr x)) (match:error x))))) (filter-map-with-index (lambda (f l) (letrec ((mapi (lambda (l i) (cond ((null? l) (quote ())) ((f (car l) i) => (lambda (x) (cons x (mapi (cdr l) (+ 1 i))))) (else (mapi (cdr l) (+ 1 i))))))) (mapi l 1))))) (let ((g296 (lambda () (match:syntax-err (quasiquote ((unquote defstruct) (unquote-splicing args))) "syntax error in")))) (if (and (pair? args) (symbol? (car args)) (pair? (cdr args)) (symbol? (cadr args)) (pair? (cddr args)) (symbol? (caddr args)) (list? (cdddr args))) (let g298 ((g299 (cdddr args)) (g297 (quote ()))) (if (null? g299) ((lambda (name constructor predicate fields) (let* ((selectors (map selector-name fields)) (mutators (map mutator-name fields)) (tag (if match:runtime-structures (gensym) (quasiquote (quote (unquote (match:make-structure-tag name)))))) (vectorP (cond ((eq? match:structure-control (quote disjoint)) (quote match:primitive-vector?)) ((eq? match:structure-control (quote vector)) (quote vector?))))) (cond ((eq? match:structure-control (quote disjoint)) (if (eq? vector? match:primitive-vector?) (set! vector? (lambda (v) (and (match:primitive-vector? v) (or (zero? (vector-length v)) (not (symbol? (vector-ref v 0))) (not (match:structure? (vector-ref v 0)))))))) (if (not (memq predicate match:disjoint-predicates)) (set! match:disjoint-predicates (cons predicate match:disjoint-predicates)))) ((eq? match:structure-control (quote vector)) (if (not (memq predicate match:vector-structures)) (set! match:vector-structures (cons predicate match:vector-structures)))) (else (match:syntax-err (quote (vector disjoint)) "invalid value for match:structure-control, legal values are"))) (quasiquote (begin (unquote-splicing (if match:runtime-structures (quasiquote ((define (unquote tag) (match:make-structure-tag (quote (unquote name)))))) (quote ()))) (define (unquote constructor) (lambda (unquote selectors) (vector (unquote tag) (unquote-splicing selectors)))) (define (unquote predicate) (lambda (obj) (and ((unquote vectorP) obj) (= (vector-length obj) (unquote (+ 1 (length selectors)))) (eq? (vector-ref obj 0) (unquote tag))))) (unquote-splicing (filter-map-with-index (lambda (n i) (quasiquote (define (unquote n) (lambda (obj) (vector-ref obj (unquote i)))))) selectors)) (unquote-splicing (filter-map-with-index (lambda (n i) (and n (quasiquote (define (unquote n) (lambda (obj newval) (vector-set! obj (unquote i) newval)))))) mutators)))))) (car args) (cadr args) (caddr args) (reverse g297)) (if (field? (car g299)) (g298 (cdr g299) (cons (car g299) g297)) (g296)))) (g296))))) +(defmacro defstruct args (let ((field? (lambda (x) (if (symbol? x) ((lambda () #t)) (if (and (pair? x) (symbol? (car x)) (pair? (cdr x)) (symbol? (cadr x)) (null? (cddr x))) ((lambda () #t)) ((lambda () #f)))))) (selector-name (lambda (x) (if (symbol? x) ((lambda () x)) (if (and (pair? x) (symbol? (car x)) (pair? (cdr x)) (null? (cddr x))) ((lambda (s) s) (car x)) (match:error x))))) (mutator-name (lambda (x) (if (symbol? x) ((lambda () #f)) (if (and (pair? x) (pair? (cdr x)) (symbol? (cadr x)) (null? (cddr x))) ((lambda (s) s) (cadr x)) (match:error x))))) (filter-map-with-index (lambda (f l) (letrec ((mapi (lambda (l i) (cond ((null? l) (quote ())) ((f (car l) i) => (lambda (x) (cons x (mapi (cdr l) (+ 1 i))))) (else (mapi (cdr l) (+ 1 i))))))) (mapi l 1))))) (let ((g296 (lambda () (match:syntax-err (quasiquote (defstruct (unquote-splicing args))) "syntax error in")))) (if (and (pair? args) (symbol? (car args)) (pair? (cdr args)) (symbol? (cadr args)) (pair? (cddr args)) (symbol? (caddr args)) (list? (cdddr args))) (let g298 ((g299 (cdddr args)) (g297 (quote ()))) (if (null? g299) ((lambda (name constructor predicate fields) (let* ((selectors (map selector-name fields)) (mutators (map mutator-name fields)) (tag (if match:runtime-structures (gensym) (quasiquote (quote (unquote (match:make-structure-tag name)))))) (vectorP (cond ((eq? match:structure-control (quote disjoint)) (quote match:primitive-vector?)) ((eq? match:structure-control (quote vector)) (quote vector?))))) (cond ((eq? match:structure-control (quote disjoint)) (if (eq? vector? match:primitive-vector?) (set! vector? (lambda (v) (and (match:primitive-vector? v) (or (zero? (vector-length v)) (not (symbol? (vector-ref v 0))) (not (match:structure? (vector-ref v 0)))))))) (if (not (memq predicate match:disjoint-predicates)) (set! match:disjoint-predicates (cons predicate match:disjoint-predicates)))) ((eq? match:structure-control (quote vector)) (if (not (memq predicate match:vector-structures)) (set! match:vector-structures (cons predicate match:vector-structures)))) (else (match:syntax-err (quote (vector disjoint)) "invalid value for match:structure-control, legal values are"))) (quasiquote (begin (unquote-splicing (if match:runtime-structures (quasiquote ((define (unquote tag) (match:make-structure-tag (quote (unquote name)))))) (quote ()))) (define (unquote constructor) (lambda (unquote selectors) (vector (unquote tag) (unquote-splicing selectors)))) (define (unquote predicate) (lambda (obj) (and ((unquote vectorP) obj) (= (vector-length obj) (unquote (+ 1 (length selectors)))) (eq? (vector-ref obj 0) (unquote tag))))) (unquote-splicing (filter-map-with-index (lambda (n i) (quasiquote (define (unquote n) (lambda (obj) (vector-ref obj (unquote i)))))) selectors)) (unquote-splicing (filter-map-with-index (lambda (n i) (and n (quasiquote (define (unquote n) (lambda (obj newval) (vector-set! obj (unquote i) newval)))))) mutators)))))) (car args) (cadr args) (caddr args) (reverse g297)) (if (field? (car g299)) (g298 (cdr g299) (cons (car g299) g297)) (g296)))) (g296))))) (defmacro define-structure args (let ((g311 (lambda () (match:syntax-err (quasiquote (define-structure (unquote-splicing args))) "syntax error in")))) (if (and (pair? args) (pair? (car args)) (list? (cdar args))) (if (null? (cdr args)) ((lambda (name id1) (quasiquote (define-structure ((unquote name) (unquote-splicing id1)) ()))) (caar args) (cdar args)) (if (and (pair? (cdr args)) (list? (cadr args))) (let g308 ((g309 (cadr args)) (g307 (quote ())) (g306 (quote ()))) (if (null? g309) (if (null? (cddr args)) ((lambda (name id1 id2 val) (let ((mk-id (lambda (id) (if (and (pair? id) (equal? (car id) (quote @)) (pair? (cdr id)) (symbol? (cadr id)) (null? (cddr id))) ((lambda (x) x) (cadr id)) ((lambda () (quasiquote (! (unquote id))))))))) (quasiquote (define-const-structure ((unquote name) (unquote-splicing (map mk-id id1))) (unquote (map (lambda (id v) (quasiquote ((unquote (mk-id id)) (unquote v)))) id2 val)))))) (caar args) (cdar args) (reverse g306) (reverse g307)) (g311)) (if (and (pair? (car g309)) (pair? (cdar g309)) (null? (cddar g309))) (g308 (cdr g309) (cons (cadar g309) g307) (cons (caar g309) g306)) (g311)))) (g311))) (g311)))) -(defmacro define-const-structure args (let ((field? (lambda (id) (if (symbol? id) ((lambda () #t)) (if (and (pair? id) (equal? (car id) (quote !)) (pair? (cdr id)) (symbol? (cadr id)) (null? (cddr id))) ((lambda () #t)) ((lambda () #f)))))) (field-name (lambda (x) (if (symbol? x) x (cadr x)))) (has-mutator? (lambda (x) (not (symbol? x)))) (filter-map-with-index (lambda (f l) (letrec ((mapi (lambda (l i) (cond ((null? l) (quote ())) ((f (car l) i) => (lambda (x) (cons x (mapi (cdr l) (+ 1 i))))) (else (mapi (cdr l) (+ 1 i))))))) (mapi l 1)))) (symbol-append (lambda l (string->symbol (apply string-append (map (lambda (x) (cond ((symbol? x) (symbol->string x)) ((number? x) (number->string x)) (else x))) l)))))) (let ((g335 (lambda () (match:syntax-err (quasiquote (define-const-structure (unquote-splicing args))) "syntax error in")))) (if (and (pair? args) (pair? (car args)) (list? (cdar args))) (if (null? (cdr args)) ((lambda (name id1) (quasiquote (define-const-structure ((unquote name) (unquote-splicing id1)) ()))) (caar args) (cdar args)) (if (symbol? (caar args)) (let g328 ((g329 (cdar args)) (g327 (quote ()))) (if (null? g329) (if (and (pair? (cdr args)) (list? (cadr args))) (let g332 ((g333 (cadr args)) (g331 (quote ())) (g330 (quote ()))) (if (null? g333) (if (null? (cddr args)) ((lambda (name id1 id2 val) (let* ((id1id2 (append id1 id2)) (raw-constructor (symbol-append (quote make-raw-) name)) (constructor (symbol-append (quote make-) name)) (predicate (symbol-append name (quote ?)))) (quasiquote (begin ((unquote defstruct) (unquote name) (unquote raw-constructor) (unquote predicate) (unquote-splicing (filter-map-with-index (lambda (arg i) (if (has-mutator? arg) (quasiquote ((unquote (symbol-append name (quote -) i)) (unquote (symbol-append (quote set-) name (quote -) i (quote !))))) (symbol-append name (quote -) i))) id1id2))) (unquote (if (null? id2) (quasiquote (define (unquote constructor) (unquote raw-constructor))) (let* ((make-fresh (lambda (x) (if (eq? (quote _) x) (gensym) x))) (names1 (map make-fresh (map field-name id1))) (names2 (map make-fresh (map field-name id2)))) (quasiquote (define (unquote constructor) (lambda (unquote names1) (let* (unquote (map list names2 val)) ((unquote raw-constructor) (unquote-splicing names1) (unquote-splicing names2))))))))) (unquote-splicing (filter-map-with-index (lambda (field i) (if (eq? (field-name field) (quote _)) #f (quasiquote (define (unquote (symbol-append name (quote -) (field-name field))) (unquote (symbol-append name (quote -) i)))))) id1id2)) (unquote-splicing (filter-map-with-index (lambda (field i) (if (or (eq? (field-name field) (quote _)) (not (has-mutator? field))) #f (quasiquote (define (unquote (symbol-append (quote set-) name (quote -) (field-name field) (quote !))) (unquote (symbol-append (quote set-) name (quote -) i (quote !))))))) id1id2)))))) (caar args) (reverse g327) (reverse g330) (reverse g331)) (g335)) (if (and (pair? (car g333)) (field? (caar g333)) (pair? (cdar g333)) (null? (cddar g333))) (g332 (cdr g333) (cons (cadar g333) g331) (cons (caar g333) g330)) (g335)))) (g335)) (if (field? (car g329)) (g328 (cdr g329) (cons (car g329) g327)) (g335)))) (g335))) (g335))))) +(defmacro define-const-structure args (let ((field? (lambda (id) (if (symbol? id) ((lambda () #t)) (if (and (pair? id) (equal? (car id) (quote !)) (pair? (cdr id)) (symbol? (cadr id)) (null? (cddr id))) ((lambda () #t)) ((lambda () #f)))))) (field-name (lambda (x) (if (symbol? x) x (cadr x)))) (has-mutator? (lambda (x) (not (symbol? x)))) (filter-map-with-index (lambda (f l) (letrec ((mapi (lambda (l i) (cond ((null? l) (quote ())) ((f (car l) i) => (lambda (x) (cons x (mapi (cdr l) (+ 1 i))))) (else (mapi (cdr l) (+ 1 i))))))) (mapi l 1)))) (symbol-append (lambda l (string->symbol (apply string-append (map (lambda (x) (cond ((symbol? x) (symbol->string x)) ((number? x) (number->string x)) (else x))) l)))))) (let ((g335 (lambda () (match:syntax-err (quasiquote (define-const-structure (unquote-splicing args))) "syntax error in")))) (if (and (pair? args) (pair? (car args)) (list? (cdar args))) (if (null? (cdr args)) ((lambda (name id1) (quasiquote (define-const-structure ((unquote name) (unquote-splicing id1)) ()))) (caar args) (cdar args)) (if (symbol? (caar args)) (let g328 ((g329 (cdar args)) (g327 (quote ()))) (if (null? g329) (if (and (pair? (cdr args)) (list? (cadr args))) (let g332 ((g333 (cadr args)) (g331 (quote ())) (g330 (quote ()))) (if (null? g333) (if (null? (cddr args)) ((lambda (name id1 id2 val) (let* ((id1id2 (append id1 id2)) (raw-constructor (symbol-append (quote make-raw-) name)) (constructor (symbol-append (quote make-) name)) (predicate (symbol-append name (quote ?)))) (quasiquote (begin (defstruct (unquote name) (unquote raw-constructor) (unquote predicate) (unquote-splicing (filter-map-with-index (lambda (arg i) (if (has-mutator? arg) (quasiquote ((unquote (symbol-append name (quote -) i)) (unquote (symbol-append (quote set-) name (quote -) i (quote !))))) (symbol-append name (quote -) i))) id1id2))) (unquote (if (null? id2) (quasiquote (define (unquote constructor) (unquote raw-constructor))) (let* ((make-fresh (lambda (x) (if (eq? (quote _) x) (gensym) x))) (names1 (map make-fresh (map field-name id1))) (names2 (map make-fresh (map field-name id2)))) (quasiquote (define (unquote constructor) (lambda (unquote names1) (let* (unquote (map list names2 val)) ((unquote raw-constructor) (unquote-splicing names1) (unquote-splicing names2))))))))) (unquote-splicing (filter-map-with-index (lambda (field i) (if (eq? (field-name field) (quote _)) #f (quasiquote (define (unquote (symbol-append name (quote -) (field-name field))) (unquote (symbol-append name (quote -) i)))))) id1id2)) (unquote-splicing (filter-map-with-index (lambda (field i) (if (or (eq? (field-name field) (quote _)) (not (has-mutator? field))) #f (quasiquote (define (unquote (symbol-append (quote set-) name (quote -) (field-name field) (quote !))) (unquote (symbol-append (quote set-) name (quote -) i (quote !))))))) id1id2)))))) (caar args) (reverse g327) (reverse g330) (reverse g331)) (g335)) (if (and (pair? (car g333)) (field? (caar g333)) (pair? (cdar g333)) (null? (cddar g333))) (g332 (cdr g333) (cons (cadar g333) g331) (cons (caar g333) g330)) (g335)))) (g335)) (if (field? (car g329)) (g328 (cdr g329) (cons (car g329) g327)) (g335)))) (g335))) (g335))))) diff --git a/module/ice-9/networking.scm b/module/ice-9/networking.scm index c0218821f..7e84f0969 100644 --- a/module/ice-9/networking.scm +++ b/module/ice-9/networking.scm @@ -5,7 +5,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -17,6 +17,9 @@ ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;;;; +(eval-when (compile) + (set-current-module (resolve-module '(guile)))) + (define (gethostbyaddr addr) (gethost addr)) (define (gethostbyname name) (gethost name)) diff --git a/module/ice-9/null.scm b/module/ice-9/null.scm index b9212e605..58b271e31 100644 --- a/module/ice-9/null.scm +++ b/module/ice-9/null.scm @@ -3,7 +3,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -18,7 +18,6 @@ ;;;; The null environment - only syntactic bindings (define-module (ice-9 null) - :use-module (ice-9 syncase) :re-export-syntax (define quote lambda if set! cond case and or diff --git a/module/ice-9/occam-channel.scm b/module/ice-9/occam-channel.scm index e28f73d3b..ea1154b52 100644 --- a/module/ice-9/occam-channel.scm +++ b/module/ice-9/occam-channel.scm @@ -2,22 +2,21 @@ ;;; Copyright (C) 2003, 2006 Free Software Foundation, Inc. ;;; -;; This library is free software; you can redistribute it and/or -;; modify it under the terms of the GNU Lesser General Public -;; License as published by the Free Software Foundation; either -;; version 2.1 of the License, or (at your option) any later version. -;; -;; This library is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;; Lesser General Public License for more details. -;; -;; You should have received a copy of the GNU Lesser General Public -;; License along with this library; if not, write to the Free Software -;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (define-module (ice-9 occam-channel) - #:use-syntax (ice-9 syncase) #:use-module (oop goops) #:use-module (ice-9 threads) #:export-syntax (alt diff --git a/module/ice-9/optargs.scm b/module/ice-9/optargs.scm index 4dea92fd7..3093e15a4 100644 --- a/module/ice-9/optargs.scm +++ b/module/ice-9/optargs.scm @@ -5,7 +5,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -410,15 +410,11 @@ ;; (defmacro* transmorgify (a #:optional b) (defmacro defmacro* (NAME ARGLIST . BODY) - (defmacro*-guts 'define NAME ARGLIST BODY)) + `(define-macro ,NAME #f (lambda* ,ARGLIST ,@BODY))) (defmacro defmacro*-public (NAME ARGLIST . BODY) - (defmacro*-guts 'define-public NAME ARGLIST BODY)) - -;; The guts of defmacro* and defmacro*-public -(define (defmacro*-guts DT NAME ARGLIST BODY) - `(,DT ,NAME - (,(lambda (transformer) (defmacro:transformer transformer)) - (lambda* ,ARGLIST ,@BODY)))) + `(begin + (defmacro* ,NAME ,ARGLIST ,@BODY) + (export-syntax ,NAME))) ;;; optargs.scm ends here diff --git a/module/ice-9/poe.scm b/module/ice-9/poe.scm index fe963db08..e7b6e3a75 100644 --- a/module/ice-9/poe.scm +++ b/module/ice-9/poe.scm @@ -5,7 +5,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/module/ice-9/popen.scm b/module/ice-9/popen.scm index 275faaa0c..1a1892851 100644 --- a/module/ice-9/popen.scm +++ b/module/ice-9/popen.scm @@ -5,7 +5,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/module/ice-9/posix.scm b/module/ice-9/posix.scm index 53d01a026..a1be33c19 100644 --- a/module/ice-9/posix.scm +++ b/module/ice-9/posix.scm @@ -5,7 +5,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -17,6 +17,9 @@ ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;;;; +(eval-when (compile) + (set-current-module (resolve-module '(guile)))) + (define (stat:dev f) (vector-ref f 0)) (define (stat:ino f) (vector-ref f 1)) (define (stat:mode f) (vector-ref f 2)) diff --git a/module/ice-9/pretty-print.scm b/module/ice-9/pretty-print.scm index bef76ddcb..0ce6a8003 100644 --- a/module/ice-9/pretty-print.scm +++ b/module/ice-9/pretty-print.scm @@ -5,7 +5,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/module/ice-9/psyntax-pp.scm b/module/ice-9/psyntax-pp.scm index 1fde489a8..fecd2b25d 100644 --- a/module/ice-9/psyntax-pp.scm +++ b/module/ice-9/psyntax-pp.scm @@ -1,11 +1,12150 @@ -(letrec ((syntmp-lambda-var-list-151 (lambda (syntmp-vars-536) (let syntmp-lvl-537 ((syntmp-vars-538 syntmp-vars-536) (syntmp-ls-539 (quote ())) (syntmp-w-540 (quote (())))) (cond ((pair? syntmp-vars-538) (syntmp-lvl-537 (cdr syntmp-vars-538) (cons (syntmp-wrap-130 (car syntmp-vars-538) syntmp-w-540) syntmp-ls-539) syntmp-w-540)) ((syntmp-id?-102 syntmp-vars-538) (cons (syntmp-wrap-130 syntmp-vars-538 syntmp-w-540) syntmp-ls-539)) ((null? syntmp-vars-538) syntmp-ls-539) ((syntmp-syntax-object?-88 syntmp-vars-538) (syntmp-lvl-537 (syntmp-syntax-object-expression-89 syntmp-vars-538) syntmp-ls-539 (syntmp-join-wraps-121 syntmp-w-540 (syntmp-syntax-object-wrap-90 syntmp-vars-538)))) ((annotation? syntmp-vars-538) (syntmp-lvl-537 (annotation-expression syntmp-vars-538) syntmp-ls-539 syntmp-w-540)) (else (cons syntmp-vars-538 syntmp-ls-539)))))) (syntmp-gen-var-150 (lambda (syntmp-id-541) (let ((syntmp-id-542 (if (syntmp-syntax-object?-88 syntmp-id-541) (syntmp-syntax-object-expression-89 syntmp-id-541) syntmp-id-541))) (if (annotation? syntmp-id-542) (syntmp-build-annotated-81 (annotation-source syntmp-id-542) (gensym (symbol->string (annotation-expression syntmp-id-542)))) (syntmp-build-annotated-81 #f (gensym (symbol->string syntmp-id-542))))))) (syntmp-strip-149 (lambda (syntmp-x-543 syntmp-w-544) (if (memq (quote top) (syntmp-wrap-marks-105 syntmp-w-544)) (if (or (annotation? syntmp-x-543) (and (pair? syntmp-x-543) (annotation? (car syntmp-x-543)))) (syntmp-strip-annotation-148 syntmp-x-543 #f) syntmp-x-543) (let syntmp-f-545 ((syntmp-x-546 syntmp-x-543)) (cond ((syntmp-syntax-object?-88 syntmp-x-546) (syntmp-strip-149 (syntmp-syntax-object-expression-89 syntmp-x-546) (syntmp-syntax-object-wrap-90 syntmp-x-546))) ((pair? syntmp-x-546) (let ((syntmp-a-547 (syntmp-f-545 (car syntmp-x-546))) (syntmp-d-548 (syntmp-f-545 (cdr syntmp-x-546)))) (if (and (eq? syntmp-a-547 (car syntmp-x-546)) (eq? syntmp-d-548 (cdr syntmp-x-546))) syntmp-x-546 (cons syntmp-a-547 syntmp-d-548)))) ((vector? syntmp-x-546) (let ((syntmp-old-549 (vector->list syntmp-x-546))) (let ((syntmp-new-550 (map syntmp-f-545 syntmp-old-549))) (if (andmap eq? syntmp-old-549 syntmp-new-550) syntmp-x-546 (list->vector syntmp-new-550))))) (else syntmp-x-546)))))) (syntmp-strip-annotation-148 (lambda (syntmp-x-551 syntmp-parent-552) (cond ((pair? syntmp-x-551) (let ((syntmp-new-553 (cons #f #f))) (begin (if syntmp-parent-552 (set-annotation-stripped! syntmp-parent-552 syntmp-new-553)) (set-car! syntmp-new-553 (syntmp-strip-annotation-148 (car syntmp-x-551) #f)) (set-cdr! syntmp-new-553 (syntmp-strip-annotation-148 (cdr syntmp-x-551) #f)) syntmp-new-553))) ((annotation? syntmp-x-551) (or (annotation-stripped syntmp-x-551) (syntmp-strip-annotation-148 (annotation-expression syntmp-x-551) syntmp-x-551))) ((vector? syntmp-x-551) (let ((syntmp-new-554 (make-vector (vector-length syntmp-x-551)))) (begin (if syntmp-parent-552 (set-annotation-stripped! syntmp-parent-552 syntmp-new-554)) (let syntmp-loop-555 ((syntmp-i-556 (- (vector-length syntmp-x-551) 1))) (unless (syntmp-fx<-75 syntmp-i-556 0) (vector-set! syntmp-new-554 syntmp-i-556 (syntmp-strip-annotation-148 (vector-ref syntmp-x-551 syntmp-i-556) #f)) (syntmp-loop-555 (syntmp-fx--73 syntmp-i-556 1)))) syntmp-new-554))) (else syntmp-x-551)))) (syntmp-ellipsis?-147 (lambda (syntmp-x-557) (and (syntmp-nonsymbol-id?-101 syntmp-x-557) (syntmp-free-id=?-125 syntmp-x-557 (quote #(syntax-object ... ((top) #(ribcage () () ()) #(ribcage #(x) #((top)) #("i")) #(ribcage (lambda-var-list gen-var strip strip-annotation ellipsis? chi-void eval-local-transformer chi-local-syntax chi-lambda-clause chi-body chi-macro chi-application chi-expr chi chi-top syntax-type chi-when-list chi-install-global chi-top-sequence chi-sequence source-wrap wrap bound-id-member? distinct-bound-ids? valid-bound-ids? bound-id=? free-id=? id-var-name same-marks? join-marks join-wraps smart-append make-binding-wrap extend-ribcage! make-empty-ribcage new-mark anti-mark the-anti-mark top-marked? top-wrap empty-wrap set-ribcage-labels! set-ribcage-marks! set-ribcage-symnames! ribcage-labels ribcage-marks ribcage-symnames ribcage? make-ribcage gen-labels gen-label make-rename rename-marks rename-new rename-old subst-rename? wrap-subst wrap-marks make-wrap id-sym-name&marks id-sym-name id? nonsymbol-id? global-extend lookup macros-only-env extend-var-env extend-env null-env binding-value binding-type make-binding arg-check source-annotation no-source unannotate set-syntax-object-wrap! set-syntax-object-expression! syntax-object-wrap syntax-object-expression syntax-object? make-syntax-object build-lexical-var build-letrec build-named-let build-let build-sequence build-data build-primref build-lambda build-global-definition build-global-assignment build-global-reference build-lexical-assignment build-lexical-reference build-conditional build-application build-annotated get-global-definition-hook put-global-definition-hook gensym-hook error-hook local-eval-hook top-level-eval-hook fx< fx= fx- fx+ noexpand) ((top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top)) ("i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i")) #(ribcage (define-structure) ((top)) ("i"))))))))) (syntmp-chi-void-146 (lambda () (syntmp-build-annotated-81 #f (list (syntmp-build-annotated-81 #f (quote void)))))) (syntmp-eval-local-transformer-145 (lambda (syntmp-expanded-558) (let ((syntmp-p-559 (syntmp-local-eval-hook-77 syntmp-expanded-558))) (if (procedure? syntmp-p-559) syntmp-p-559 (syntax-error syntmp-p-559 "nonprocedure transformer"))))) (syntmp-chi-local-syntax-144 (lambda (syntmp-rec?-560 syntmp-e-561 syntmp-r-562 syntmp-w-563 syntmp-s-564 syntmp-k-565) ((lambda (syntmp-tmp-566) ((lambda (syntmp-tmp-567) (if syntmp-tmp-567 (apply (lambda (syntmp-_-568 syntmp-id-569 syntmp-val-570 syntmp-e1-571 syntmp-e2-572) (let ((syntmp-ids-573 syntmp-id-569)) (if (not (syntmp-valid-bound-ids?-127 syntmp-ids-573)) (syntax-error syntmp-e-561 "duplicate bound keyword in") (let ((syntmp-labels-575 (syntmp-gen-labels-108 syntmp-ids-573))) (let ((syntmp-new-w-576 (syntmp-make-binding-wrap-119 syntmp-ids-573 syntmp-labels-575 syntmp-w-563))) (syntmp-k-565 (cons syntmp-e1-571 syntmp-e2-572) (syntmp-extend-env-96 syntmp-labels-575 (let ((syntmp-w-578 (if syntmp-rec?-560 syntmp-new-w-576 syntmp-w-563)) (syntmp-trans-r-579 (syntmp-macros-only-env-98 syntmp-r-562))) (map (lambda (syntmp-x-580) (cons (quote macro) (syntmp-eval-local-transformer-145 (syntmp-chi-138 syntmp-x-580 syntmp-trans-r-579 syntmp-w-578)))) syntmp-val-570)) syntmp-r-562) syntmp-new-w-576 syntmp-s-564)))))) syntmp-tmp-567) ((lambda (syntmp-_-582) (syntax-error (syntmp-source-wrap-131 syntmp-e-561 syntmp-w-563 syntmp-s-564))) syntmp-tmp-566))) (syntax-dispatch syntmp-tmp-566 (quote (any #(each (any any)) any . each-any))))) syntmp-e-561))) (syntmp-chi-lambda-clause-143 (lambda (syntmp-e-583 syntmp-c-584 syntmp-r-585 syntmp-w-586 syntmp-k-587) ((lambda (syntmp-tmp-588) ((lambda (syntmp-tmp-589) (if syntmp-tmp-589 (apply (lambda (syntmp-id-590 syntmp-e1-591 syntmp-e2-592) (let ((syntmp-ids-593 syntmp-id-590)) (if (not (syntmp-valid-bound-ids?-127 syntmp-ids-593)) (syntax-error syntmp-e-583 "invalid parameter list in") (let ((syntmp-labels-595 (syntmp-gen-labels-108 syntmp-ids-593)) (syntmp-new-vars-596 (map syntmp-gen-var-150 syntmp-ids-593))) (syntmp-k-587 syntmp-new-vars-596 (syntmp-chi-body-142 (cons syntmp-e1-591 syntmp-e2-592) syntmp-e-583 (syntmp-extend-var-env-97 syntmp-labels-595 syntmp-new-vars-596 syntmp-r-585) (syntmp-make-binding-wrap-119 syntmp-ids-593 syntmp-labels-595 syntmp-w-586))))))) syntmp-tmp-589) ((lambda (syntmp-tmp-598) (if syntmp-tmp-598 (apply (lambda (syntmp-ids-599 syntmp-e1-600 syntmp-e2-601) (let ((syntmp-old-ids-602 (syntmp-lambda-var-list-151 syntmp-ids-599))) (if (not (syntmp-valid-bound-ids?-127 syntmp-old-ids-602)) (syntax-error syntmp-e-583 "invalid parameter list in") (let ((syntmp-labels-603 (syntmp-gen-labels-108 syntmp-old-ids-602)) (syntmp-new-vars-604 (map syntmp-gen-var-150 syntmp-old-ids-602))) (syntmp-k-587 (let syntmp-f-605 ((syntmp-ls1-606 (cdr syntmp-new-vars-604)) (syntmp-ls2-607 (car syntmp-new-vars-604))) (if (null? syntmp-ls1-606) syntmp-ls2-607 (syntmp-f-605 (cdr syntmp-ls1-606) (cons (car syntmp-ls1-606) syntmp-ls2-607)))) (syntmp-chi-body-142 (cons syntmp-e1-600 syntmp-e2-601) syntmp-e-583 (syntmp-extend-var-env-97 syntmp-labels-603 syntmp-new-vars-604 syntmp-r-585) (syntmp-make-binding-wrap-119 syntmp-old-ids-602 syntmp-labels-603 syntmp-w-586))))))) syntmp-tmp-598) ((lambda (syntmp-_-609) (syntax-error syntmp-e-583)) syntmp-tmp-588))) (syntax-dispatch syntmp-tmp-588 (quote (any any . each-any)))))) (syntax-dispatch syntmp-tmp-588 (quote (each-any any . each-any))))) syntmp-c-584))) (syntmp-chi-body-142 (lambda (syntmp-body-610 syntmp-outer-form-611 syntmp-r-612 syntmp-w-613) (let ((syntmp-r-614 (cons (quote ("placeholder" placeholder)) syntmp-r-612))) (let ((syntmp-ribcage-615 (syntmp-make-ribcage-109 (quote ()) (quote ()) (quote ())))) (let ((syntmp-w-616 (syntmp-make-wrap-104 (syntmp-wrap-marks-105 syntmp-w-613) (cons syntmp-ribcage-615 (syntmp-wrap-subst-106 syntmp-w-613))))) (let syntmp-parse-617 ((syntmp-body-618 (map (lambda (syntmp-x-624) (cons syntmp-r-614 (syntmp-wrap-130 syntmp-x-624 syntmp-w-616))) syntmp-body-610)) (syntmp-ids-619 (quote ())) (syntmp-labels-620 (quote ())) (syntmp-vars-621 (quote ())) (syntmp-vals-622 (quote ())) (syntmp-bindings-623 (quote ()))) (if (null? syntmp-body-618) (syntax-error syntmp-outer-form-611 "no expressions in body") (let ((syntmp-e-625 (cdar syntmp-body-618)) (syntmp-er-626 (caar syntmp-body-618))) (call-with-values (lambda () (syntmp-syntax-type-136 syntmp-e-625 syntmp-er-626 (quote (())) #f syntmp-ribcage-615)) (lambda (syntmp-type-627 syntmp-value-628 syntmp-e-629 syntmp-w-630 syntmp-s-631) (let ((syntmp-t-632 syntmp-type-627)) (if (memv syntmp-t-632 (quote (define-form))) (let ((syntmp-id-633 (syntmp-wrap-130 syntmp-value-628 syntmp-w-630)) (syntmp-label-634 (syntmp-gen-label-107))) (let ((syntmp-var-635 (syntmp-gen-var-150 syntmp-id-633))) (begin (syntmp-extend-ribcage!-118 syntmp-ribcage-615 syntmp-id-633 syntmp-label-634) (syntmp-parse-617 (cdr syntmp-body-618) (cons syntmp-id-633 syntmp-ids-619) (cons syntmp-label-634 syntmp-labels-620) (cons syntmp-var-635 syntmp-vars-621) (cons (cons syntmp-er-626 (syntmp-wrap-130 syntmp-e-629 syntmp-w-630)) syntmp-vals-622) (cons (cons (quote lexical) syntmp-var-635) syntmp-bindings-623))))) (if (memv syntmp-t-632 (quote (define-syntax-form))) (let ((syntmp-id-636 (syntmp-wrap-130 syntmp-value-628 syntmp-w-630)) (syntmp-label-637 (syntmp-gen-label-107))) (begin (syntmp-extend-ribcage!-118 syntmp-ribcage-615 syntmp-id-636 syntmp-label-637) (syntmp-parse-617 (cdr syntmp-body-618) (cons syntmp-id-636 syntmp-ids-619) (cons syntmp-label-637 syntmp-labels-620) syntmp-vars-621 syntmp-vals-622 (cons (cons (quote macro) (cons syntmp-er-626 (syntmp-wrap-130 syntmp-e-629 syntmp-w-630))) syntmp-bindings-623)))) (if (memv syntmp-t-632 (quote (begin-form))) ((lambda (syntmp-tmp-638) ((lambda (syntmp-tmp-639) (if syntmp-tmp-639 (apply (lambda (syntmp-_-640 syntmp-e1-641) (syntmp-parse-617 (let syntmp-f-642 ((syntmp-forms-643 syntmp-e1-641)) (if (null? syntmp-forms-643) (cdr syntmp-body-618) (cons (cons syntmp-er-626 (syntmp-wrap-130 (car syntmp-forms-643) syntmp-w-630)) (syntmp-f-642 (cdr syntmp-forms-643))))) syntmp-ids-619 syntmp-labels-620 syntmp-vars-621 syntmp-vals-622 syntmp-bindings-623)) syntmp-tmp-639) (syntax-error syntmp-tmp-638))) (syntax-dispatch syntmp-tmp-638 (quote (any . each-any))))) syntmp-e-629) (if (memv syntmp-t-632 (quote (local-syntax-form))) (syntmp-chi-local-syntax-144 syntmp-value-628 syntmp-e-629 syntmp-er-626 syntmp-w-630 syntmp-s-631 (lambda (syntmp-forms-645 syntmp-er-646 syntmp-w-647 syntmp-s-648) (syntmp-parse-617 (let syntmp-f-649 ((syntmp-forms-650 syntmp-forms-645)) (if (null? syntmp-forms-650) (cdr syntmp-body-618) (cons (cons syntmp-er-646 (syntmp-wrap-130 (car syntmp-forms-650) syntmp-w-647)) (syntmp-f-649 (cdr syntmp-forms-650))))) syntmp-ids-619 syntmp-labels-620 syntmp-vars-621 syntmp-vals-622 syntmp-bindings-623))) (if (null? syntmp-ids-619) (syntmp-build-sequence-83 #f (map (lambda (syntmp-x-651) (syntmp-chi-138 (cdr syntmp-x-651) (car syntmp-x-651) (quote (())))) (cons (cons syntmp-er-626 (syntmp-source-wrap-131 syntmp-e-629 syntmp-w-630 syntmp-s-631)) (cdr syntmp-body-618)))) (begin (if (not (syntmp-valid-bound-ids?-127 syntmp-ids-619)) (syntax-error syntmp-outer-form-611 "invalid or duplicate identifier in definition")) (let syntmp-loop-652 ((syntmp-bs-653 syntmp-bindings-623) (syntmp-er-cache-654 #f) (syntmp-r-cache-655 #f)) (if (not (null? syntmp-bs-653)) (let ((syntmp-b-656 (car syntmp-bs-653))) (if (eq? (car syntmp-b-656) (quote macro)) (let ((syntmp-er-657 (cadr syntmp-b-656))) (let ((syntmp-r-cache-658 (if (eq? syntmp-er-657 syntmp-er-cache-654) syntmp-r-cache-655 (syntmp-macros-only-env-98 syntmp-er-657)))) (begin (set-cdr! syntmp-b-656 (syntmp-eval-local-transformer-145 (syntmp-chi-138 (cddr syntmp-b-656) syntmp-r-cache-658 (quote (()))))) (syntmp-loop-652 (cdr syntmp-bs-653) syntmp-er-657 syntmp-r-cache-658)))) (syntmp-loop-652 (cdr syntmp-bs-653) syntmp-er-cache-654 syntmp-r-cache-655))))) (set-cdr! syntmp-r-614 (syntmp-extend-env-96 syntmp-labels-620 syntmp-bindings-623 (cdr syntmp-r-614))) (syntmp-build-letrec-86 #f syntmp-vars-621 (map (lambda (syntmp-x-659) (syntmp-chi-138 (cdr syntmp-x-659) (car syntmp-x-659) (quote (())))) syntmp-vals-622) (syntmp-build-sequence-83 #f (map (lambda (syntmp-x-660) (syntmp-chi-138 (cdr syntmp-x-660) (car syntmp-x-660) (quote (())))) (cons (cons syntmp-er-626 (syntmp-source-wrap-131 syntmp-e-629 syntmp-w-630 syntmp-s-631)) (cdr syntmp-body-618)))))))))))))))))))))) (syntmp-chi-macro-141 (lambda (syntmp-p-661 syntmp-e-662 syntmp-r-663 syntmp-w-664 syntmp-rib-665) (letrec ((syntmp-rebuild-macro-output-666 (lambda (syntmp-x-667 syntmp-m-668) (cond ((pair? syntmp-x-667) (cons (syntmp-rebuild-macro-output-666 (car syntmp-x-667) syntmp-m-668) (syntmp-rebuild-macro-output-666 (cdr syntmp-x-667) syntmp-m-668))) ((syntmp-syntax-object?-88 syntmp-x-667) (let ((syntmp-w-669 (syntmp-syntax-object-wrap-90 syntmp-x-667))) (let ((syntmp-ms-670 (syntmp-wrap-marks-105 syntmp-w-669)) (syntmp-s-671 (syntmp-wrap-subst-106 syntmp-w-669))) (syntmp-make-syntax-object-87 (syntmp-syntax-object-expression-89 syntmp-x-667) (if (and (pair? syntmp-ms-670) (eq? (car syntmp-ms-670) #f)) (syntmp-make-wrap-104 (cdr syntmp-ms-670) (if syntmp-rib-665 (cons syntmp-rib-665 (cdr syntmp-s-671)) (cdr syntmp-s-671))) (syntmp-make-wrap-104 (cons syntmp-m-668 syntmp-ms-670) (if syntmp-rib-665 (cons syntmp-rib-665 (cons (quote shift) syntmp-s-671)) (cons (quote shift) syntmp-s-671)))))))) ((vector? syntmp-x-667) (let ((syntmp-n-672 (vector-length syntmp-x-667))) (let ((syntmp-v-673 (make-vector syntmp-n-672))) (let syntmp-doloop-674 ((syntmp-i-675 0)) (if (syntmp-fx=-74 syntmp-i-675 syntmp-n-672) syntmp-v-673 (begin (vector-set! syntmp-v-673 syntmp-i-675 (syntmp-rebuild-macro-output-666 (vector-ref syntmp-x-667 syntmp-i-675) syntmp-m-668)) (syntmp-doloop-674 (syntmp-fx+-72 syntmp-i-675 1)))))))) ((symbol? syntmp-x-667) (syntax-error syntmp-x-667 "encountered raw symbol in macro output")) (else syntmp-x-667))))) (syntmp-rebuild-macro-output-666 (syntmp-p-661 (syntmp-wrap-130 syntmp-e-662 (syntmp-anti-mark-117 syntmp-w-664))) (string #\m))))) (syntmp-chi-application-140 (lambda (syntmp-x-676 syntmp-e-677 syntmp-r-678 syntmp-w-679 syntmp-s-680) ((lambda (syntmp-tmp-681) ((lambda (syntmp-tmp-682) (if syntmp-tmp-682 (apply (lambda (syntmp-e0-683 syntmp-e1-684) (syntmp-build-annotated-81 syntmp-s-680 (cons syntmp-x-676 (map (lambda (syntmp-e-685) (syntmp-chi-138 syntmp-e-685 syntmp-r-678 syntmp-w-679)) syntmp-e1-684)))) syntmp-tmp-682) (syntax-error syntmp-tmp-681))) (syntax-dispatch syntmp-tmp-681 (quote (any . each-any))))) syntmp-e-677))) (syntmp-chi-expr-139 (lambda (syntmp-type-687 syntmp-value-688 syntmp-e-689 syntmp-r-690 syntmp-w-691 syntmp-s-692) (let ((syntmp-t-693 syntmp-type-687)) (if (memv syntmp-t-693 (quote (lexical))) (syntmp-build-annotated-81 syntmp-s-692 syntmp-value-688) (if (memv syntmp-t-693 (quote (core external-macro))) (syntmp-value-688 syntmp-e-689 syntmp-r-690 syntmp-w-691 syntmp-s-692) (if (memv syntmp-t-693 (quote (lexical-call))) (syntmp-chi-application-140 (syntmp-build-annotated-81 (syntmp-source-annotation-93 (car syntmp-e-689)) syntmp-value-688) syntmp-e-689 syntmp-r-690 syntmp-w-691 syntmp-s-692) (if (memv syntmp-t-693 (quote (global-call))) (syntmp-chi-application-140 (syntmp-build-annotated-81 (syntmp-source-annotation-93 (car syntmp-e-689)) syntmp-value-688) syntmp-e-689 syntmp-r-690 syntmp-w-691 syntmp-s-692) (if (memv syntmp-t-693 (quote (constant))) (syntmp-build-data-82 syntmp-s-692 (syntmp-strip-149 (syntmp-source-wrap-131 syntmp-e-689 syntmp-w-691 syntmp-s-692) (quote (())))) (if (memv syntmp-t-693 (quote (global))) (syntmp-build-annotated-81 syntmp-s-692 syntmp-value-688) (if (memv syntmp-t-693 (quote (call))) (syntmp-chi-application-140 (syntmp-chi-138 (car syntmp-e-689) syntmp-r-690 syntmp-w-691) syntmp-e-689 syntmp-r-690 syntmp-w-691 syntmp-s-692) (if (memv syntmp-t-693 (quote (begin-form))) ((lambda (syntmp-tmp-694) ((lambda (syntmp-tmp-695) (if syntmp-tmp-695 (apply (lambda (syntmp-_-696 syntmp-e1-697 syntmp-e2-698) (syntmp-chi-sequence-132 (cons syntmp-e1-697 syntmp-e2-698) syntmp-r-690 syntmp-w-691 syntmp-s-692)) syntmp-tmp-695) (syntax-error syntmp-tmp-694))) (syntax-dispatch syntmp-tmp-694 (quote (any any . each-any))))) syntmp-e-689) (if (memv syntmp-t-693 (quote (local-syntax-form))) (syntmp-chi-local-syntax-144 syntmp-value-688 syntmp-e-689 syntmp-r-690 syntmp-w-691 syntmp-s-692 syntmp-chi-sequence-132) (if (memv syntmp-t-693 (quote (eval-when-form))) ((lambda (syntmp-tmp-700) ((lambda (syntmp-tmp-701) (if syntmp-tmp-701 (apply (lambda (syntmp-_-702 syntmp-x-703 syntmp-e1-704 syntmp-e2-705) (let ((syntmp-when-list-706 (syntmp-chi-when-list-135 syntmp-e-689 syntmp-x-703 syntmp-w-691))) (if (memq (quote eval) syntmp-when-list-706) (syntmp-chi-sequence-132 (cons syntmp-e1-704 syntmp-e2-705) syntmp-r-690 syntmp-w-691 syntmp-s-692) (syntmp-chi-void-146)))) syntmp-tmp-701) (syntax-error syntmp-tmp-700))) (syntax-dispatch syntmp-tmp-700 (quote (any each-any any . each-any))))) syntmp-e-689) (if (memv syntmp-t-693 (quote (define-form define-syntax-form))) (syntax-error (syntmp-wrap-130 syntmp-value-688 syntmp-w-691) "invalid context for definition of") (if (memv syntmp-t-693 (quote (syntax))) (syntax-error (syntmp-source-wrap-131 syntmp-e-689 syntmp-w-691 syntmp-s-692) "reference to pattern variable outside syntax form") (if (memv syntmp-t-693 (quote (displaced-lexical))) (syntax-error (syntmp-source-wrap-131 syntmp-e-689 syntmp-w-691 syntmp-s-692) "reference to identifier outside its scope") (syntax-error (syntmp-source-wrap-131 syntmp-e-689 syntmp-w-691 syntmp-s-692)))))))))))))))))) (syntmp-chi-138 (lambda (syntmp-e-709 syntmp-r-710 syntmp-w-711) (call-with-values (lambda () (syntmp-syntax-type-136 syntmp-e-709 syntmp-r-710 syntmp-w-711 #f #f)) (lambda (syntmp-type-712 syntmp-value-713 syntmp-e-714 syntmp-w-715 syntmp-s-716) (syntmp-chi-expr-139 syntmp-type-712 syntmp-value-713 syntmp-e-714 syntmp-r-710 syntmp-w-715 syntmp-s-716))))) (syntmp-chi-top-137 (lambda (syntmp-e-717 syntmp-r-718 syntmp-w-719 syntmp-m-720 syntmp-esew-721) (call-with-values (lambda () (syntmp-syntax-type-136 syntmp-e-717 syntmp-r-718 syntmp-w-719 #f #f)) (lambda (syntmp-type-734 syntmp-value-735 syntmp-e-736 syntmp-w-737 syntmp-s-738) (let ((syntmp-t-739 syntmp-type-734)) (if (memv syntmp-t-739 (quote (begin-form))) ((lambda (syntmp-tmp-740) ((lambda (syntmp-tmp-741) (if syntmp-tmp-741 (apply (lambda (syntmp-_-742) (syntmp-chi-void-146)) syntmp-tmp-741) ((lambda (syntmp-tmp-743) (if syntmp-tmp-743 (apply (lambda (syntmp-_-744 syntmp-e1-745 syntmp-e2-746) (syntmp-chi-top-sequence-133 (cons syntmp-e1-745 syntmp-e2-746) syntmp-r-718 syntmp-w-737 syntmp-s-738 syntmp-m-720 syntmp-esew-721)) syntmp-tmp-743) (syntax-error syntmp-tmp-740))) (syntax-dispatch syntmp-tmp-740 (quote (any any . each-any)))))) (syntax-dispatch syntmp-tmp-740 (quote (any))))) syntmp-e-736) (if (memv syntmp-t-739 (quote (local-syntax-form))) (syntmp-chi-local-syntax-144 syntmp-value-735 syntmp-e-736 syntmp-r-718 syntmp-w-737 syntmp-s-738 (lambda (syntmp-body-748 syntmp-r-749 syntmp-w-750 syntmp-s-751) (syntmp-chi-top-sequence-133 syntmp-body-748 syntmp-r-749 syntmp-w-750 syntmp-s-751 syntmp-m-720 syntmp-esew-721))) (if (memv syntmp-t-739 (quote (eval-when-form))) ((lambda (syntmp-tmp-752) ((lambda (syntmp-tmp-753) (if syntmp-tmp-753 (apply (lambda (syntmp-_-754 syntmp-x-755 syntmp-e1-756 syntmp-e2-757) (let ((syntmp-when-list-758 (syntmp-chi-when-list-135 syntmp-e-736 syntmp-x-755 syntmp-w-737)) (syntmp-body-759 (cons syntmp-e1-756 syntmp-e2-757))) (cond ((eq? syntmp-m-720 (quote e)) (if (memq (quote eval) syntmp-when-list-758) (syntmp-chi-top-sequence-133 syntmp-body-759 syntmp-r-718 syntmp-w-737 syntmp-s-738 (quote e) (quote (eval))) (syntmp-chi-void-146))) ((memq (quote load) syntmp-when-list-758) (if (or (memq (quote compile) syntmp-when-list-758) (and (eq? syntmp-m-720 (quote c&e)) (memq (quote eval) syntmp-when-list-758))) (syntmp-chi-top-sequence-133 syntmp-body-759 syntmp-r-718 syntmp-w-737 syntmp-s-738 (quote c&e) (quote (compile load))) (if (memq syntmp-m-720 (quote (c c&e))) (syntmp-chi-top-sequence-133 syntmp-body-759 syntmp-r-718 syntmp-w-737 syntmp-s-738 (quote c) (quote (load))) (syntmp-chi-void-146)))) ((or (memq (quote compile) syntmp-when-list-758) (and (eq? syntmp-m-720 (quote c&e)) (memq (quote eval) syntmp-when-list-758))) (syntmp-top-level-eval-hook-76 (syntmp-chi-top-sequence-133 syntmp-body-759 syntmp-r-718 syntmp-w-737 syntmp-s-738 (quote e) (quote (eval)))) (syntmp-chi-void-146)) (else (syntmp-chi-void-146))))) syntmp-tmp-753) (syntax-error syntmp-tmp-752))) (syntax-dispatch syntmp-tmp-752 (quote (any each-any any . each-any))))) syntmp-e-736) (if (memv syntmp-t-739 (quote (define-syntax-form))) (let ((syntmp-n-762 (syntmp-id-var-name-124 syntmp-value-735 syntmp-w-737)) (syntmp-r-763 (syntmp-macros-only-env-98 syntmp-r-718))) (let ((syntmp-t-764 syntmp-m-720)) (if (memv syntmp-t-764 (quote (c))) (if (memq (quote compile) syntmp-esew-721) (let ((syntmp-e-765 (syntmp-chi-install-global-134 syntmp-n-762 (syntmp-chi-138 syntmp-e-736 syntmp-r-763 syntmp-w-737)))) (begin (syntmp-top-level-eval-hook-76 syntmp-e-765) (if (memq (quote load) syntmp-esew-721) syntmp-e-765 (syntmp-chi-void-146)))) (if (memq (quote load) syntmp-esew-721) (syntmp-chi-install-global-134 syntmp-n-762 (syntmp-chi-138 syntmp-e-736 syntmp-r-763 syntmp-w-737)) (syntmp-chi-void-146))) (if (memv syntmp-t-764 (quote (c&e))) (let ((syntmp-e-766 (syntmp-chi-install-global-134 syntmp-n-762 (syntmp-chi-138 syntmp-e-736 syntmp-r-763 syntmp-w-737)))) (begin (syntmp-top-level-eval-hook-76 syntmp-e-766) syntmp-e-766)) (begin (if (memq (quote eval) syntmp-esew-721) (syntmp-top-level-eval-hook-76 (syntmp-chi-install-global-134 syntmp-n-762 (syntmp-chi-138 syntmp-e-736 syntmp-r-763 syntmp-w-737)))) (syntmp-chi-void-146)))))) (if (memv syntmp-t-739 (quote (define-form))) (let ((syntmp-n-767 (syntmp-id-var-name-124 syntmp-value-735 syntmp-w-737))) (let ((syntmp-type-768 (syntmp-binding-type-94 (syntmp-lookup-99 syntmp-n-767 syntmp-r-718)))) (let ((syntmp-t-769 syntmp-type-768)) (if (memv syntmp-t-769 (quote (global))) (let ((syntmp-x-770 (syntmp-build-annotated-81 syntmp-s-738 (list (quote define) syntmp-n-767 (syntmp-chi-138 syntmp-e-736 syntmp-r-718 syntmp-w-737))))) (begin (if (eq? syntmp-m-720 (quote c&e)) (syntmp-top-level-eval-hook-76 syntmp-x-770)) syntmp-x-770)) (if (memv syntmp-t-769 (quote (displaced-lexical))) (syntax-error (syntmp-wrap-130 syntmp-value-735 syntmp-w-737) "identifier out of context") (if (eq? syntmp-type-768 (quote external-macro)) (let ((syntmp-x-771 (syntmp-build-annotated-81 syntmp-s-738 (list (quote define) syntmp-n-767 (syntmp-chi-138 syntmp-e-736 syntmp-r-718 syntmp-w-737))))) (begin (if (eq? syntmp-m-720 (quote c&e)) (syntmp-top-level-eval-hook-76 syntmp-x-771)) syntmp-x-771)) (syntax-error (syntmp-wrap-130 syntmp-value-735 syntmp-w-737) "cannot define keyword at top level"))))))) (let ((syntmp-x-772 (syntmp-chi-expr-139 syntmp-type-734 syntmp-value-735 syntmp-e-736 syntmp-r-718 syntmp-w-737 syntmp-s-738))) (begin (if (eq? syntmp-m-720 (quote c&e)) (syntmp-top-level-eval-hook-76 syntmp-x-772)) syntmp-x-772)))))))))))) (syntmp-syntax-type-136 (lambda (syntmp-e-773 syntmp-r-774 syntmp-w-775 syntmp-s-776 syntmp-rib-777) (cond ((symbol? syntmp-e-773) (let ((syntmp-n-778 (syntmp-id-var-name-124 syntmp-e-773 syntmp-w-775))) (let ((syntmp-b-779 (syntmp-lookup-99 syntmp-n-778 syntmp-r-774))) (let ((syntmp-type-780 (syntmp-binding-type-94 syntmp-b-779))) (let ((syntmp-t-781 syntmp-type-780)) (if (memv syntmp-t-781 (quote (lexical))) (values syntmp-type-780 (syntmp-binding-value-95 syntmp-b-779) syntmp-e-773 syntmp-w-775 syntmp-s-776) (if (memv syntmp-t-781 (quote (global))) (values syntmp-type-780 syntmp-n-778 syntmp-e-773 syntmp-w-775 syntmp-s-776) (if (memv syntmp-t-781 (quote (macro))) (syntmp-syntax-type-136 (syntmp-chi-macro-141 (syntmp-binding-value-95 syntmp-b-779) syntmp-e-773 syntmp-r-774 syntmp-w-775 syntmp-rib-777) syntmp-r-774 (quote (())) syntmp-s-776 syntmp-rib-777) (values syntmp-type-780 (syntmp-binding-value-95 syntmp-b-779) syntmp-e-773 syntmp-w-775 syntmp-s-776))))))))) ((pair? syntmp-e-773) (let ((syntmp-first-782 (car syntmp-e-773))) (if (syntmp-id?-102 syntmp-first-782) (let ((syntmp-n-783 (syntmp-id-var-name-124 syntmp-first-782 syntmp-w-775))) (let ((syntmp-b-784 (syntmp-lookup-99 syntmp-n-783 syntmp-r-774))) (let ((syntmp-type-785 (syntmp-binding-type-94 syntmp-b-784))) (let ((syntmp-t-786 syntmp-type-785)) (if (memv syntmp-t-786 (quote (lexical))) (values (quote lexical-call) (syntmp-binding-value-95 syntmp-b-784) syntmp-e-773 syntmp-w-775 syntmp-s-776) (if (memv syntmp-t-786 (quote (global))) (values (quote global-call) syntmp-n-783 syntmp-e-773 syntmp-w-775 syntmp-s-776) (if (memv syntmp-t-786 (quote (macro))) (syntmp-syntax-type-136 (syntmp-chi-macro-141 (syntmp-binding-value-95 syntmp-b-784) syntmp-e-773 syntmp-r-774 syntmp-w-775 syntmp-rib-777) syntmp-r-774 (quote (())) syntmp-s-776 syntmp-rib-777) (if (memv syntmp-t-786 (quote (core external-macro))) (values syntmp-type-785 (syntmp-binding-value-95 syntmp-b-784) syntmp-e-773 syntmp-w-775 syntmp-s-776) (if (memv syntmp-t-786 (quote (local-syntax))) (values (quote local-syntax-form) (syntmp-binding-value-95 syntmp-b-784) syntmp-e-773 syntmp-w-775 syntmp-s-776) (if (memv syntmp-t-786 (quote (begin))) (values (quote begin-form) #f syntmp-e-773 syntmp-w-775 syntmp-s-776) (if (memv syntmp-t-786 (quote (eval-when))) (values (quote eval-when-form) #f syntmp-e-773 syntmp-w-775 syntmp-s-776) (if (memv syntmp-t-786 (quote (define))) ((lambda (syntmp-tmp-787) ((lambda (syntmp-tmp-788) (if (if syntmp-tmp-788 (apply (lambda (syntmp-_-789 syntmp-name-790 syntmp-val-791) (syntmp-id?-102 syntmp-name-790)) syntmp-tmp-788) #f) (apply (lambda (syntmp-_-792 syntmp-name-793 syntmp-val-794) (values (quote define-form) syntmp-name-793 syntmp-val-794 syntmp-w-775 syntmp-s-776)) syntmp-tmp-788) ((lambda (syntmp-tmp-795) (if (if syntmp-tmp-795 (apply (lambda (syntmp-_-796 syntmp-name-797 syntmp-args-798 syntmp-e1-799 syntmp-e2-800) (and (syntmp-id?-102 syntmp-name-797) (syntmp-valid-bound-ids?-127 (syntmp-lambda-var-list-151 syntmp-args-798)))) syntmp-tmp-795) #f) (apply (lambda (syntmp-_-801 syntmp-name-802 syntmp-args-803 syntmp-e1-804 syntmp-e2-805) (values (quote define-form) (syntmp-wrap-130 syntmp-name-802 syntmp-w-775) (cons (quote #(syntax-object lambda ((top) #(ribcage #(_ name args e1 e2) #((top) (top) (top) (top) (top)) #("i" "i" "i" "i" "i")) #(ribcage () () ()) #(ribcage #(t) #(("m" top)) #("i")) #(ribcage () () ()) #(ribcage () () ()) #(ribcage () () ()) #(ribcage #(type) #((top)) #("i")) #(ribcage () () ()) #(ribcage #(b) #((top)) #("i")) #(ribcage () () ()) #(ribcage #(n) #((top)) #("i")) #(ribcage () () ()) #(ribcage #(first) #((top)) #("i")) #(ribcage () () ()) #(ribcage #(e r w s rib) #((top) (top) (top) (top) (top)) #("i" "i" "i" "i" "i")) #(ribcage (lambda-var-list gen-var strip strip-annotation ellipsis? chi-void eval-local-transformer chi-local-syntax chi-lambda-clause chi-body chi-macro chi-application chi-expr chi chi-top syntax-type chi-when-list chi-install-global chi-top-sequence chi-sequence source-wrap wrap bound-id-member? distinct-bound-ids? valid-bound-ids? bound-id=? free-id=? id-var-name same-marks? join-marks join-wraps smart-append make-binding-wrap extend-ribcage! make-empty-ribcage new-mark anti-mark the-anti-mark top-marked? top-wrap empty-wrap set-ribcage-labels! set-ribcage-marks! set-ribcage-symnames! ribcage-labels ribcage-marks ribcage-symnames ribcage? make-ribcage gen-labels gen-label make-rename rename-marks rename-new rename-old subst-rename? wrap-subst wrap-marks make-wrap id-sym-name&marks id-sym-name id? nonsymbol-id? global-extend lookup macros-only-env extend-var-env extend-env null-env binding-value binding-type make-binding arg-check source-annotation no-source unannotate set-syntax-object-wrap! set-syntax-object-expression! syntax-object-wrap syntax-object-expression syntax-object? make-syntax-object build-lexical-var build-letrec build-named-let build-let build-sequence build-data build-primref build-lambda build-global-definition build-global-assignment build-global-reference build-lexical-assignment build-lexical-reference build-conditional build-application build-annotated get-global-definition-hook put-global-definition-hook gensym-hook error-hook local-eval-hook top-level-eval-hook fx< fx= fx- fx+ noexpand) ((top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top)) ("i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i")) #(ribcage (define-structure) ((top)) ("i"))))) (syntmp-wrap-130 (cons syntmp-args-803 (cons syntmp-e1-804 syntmp-e2-805)) syntmp-w-775)) (quote (())) syntmp-s-776)) syntmp-tmp-795) ((lambda (syntmp-tmp-807) (if (if syntmp-tmp-807 (apply (lambda (syntmp-_-808 syntmp-name-809) (syntmp-id?-102 syntmp-name-809)) syntmp-tmp-807) #f) (apply (lambda (syntmp-_-810 syntmp-name-811) (values (quote define-form) (syntmp-wrap-130 syntmp-name-811 syntmp-w-775) (quote (#(syntax-object void ((top) #(ribcage #(_ name) #((top) (top)) #("i" "i")) #(ribcage () () ()) #(ribcage #(t) #(("m" top)) #("i")) #(ribcage () () ()) #(ribcage () () ()) #(ribcage () () ()) #(ribcage #(type) #((top)) #("i")) #(ribcage () () ()) #(ribcage #(b) #((top)) #("i")) #(ribcage () () ()) #(ribcage #(n) #((top)) #("i")) #(ribcage () () ()) #(ribcage #(first) #((top)) #("i")) #(ribcage () () ()) #(ribcage #(e r w s rib) #((top) (top) (top) (top) (top)) #("i" "i" "i" "i" "i")) #(ribcage (lambda-var-list gen-var strip strip-annotation ellipsis? chi-void eval-local-transformer chi-local-syntax chi-lambda-clause chi-body chi-macro chi-application chi-expr chi chi-top syntax-type chi-when-list chi-install-global chi-top-sequence chi-sequence source-wrap wrap bound-id-member? distinct-bound-ids? valid-bound-ids? bound-id=? free-id=? id-var-name same-marks? join-marks join-wraps smart-append make-binding-wrap extend-ribcage! make-empty-ribcage new-mark anti-mark the-anti-mark top-marked? top-wrap empty-wrap set-ribcage-labels! set-ribcage-marks! set-ribcage-symnames! ribcage-labels ribcage-marks ribcage-symnames ribcage? make-ribcage gen-labels gen-label make-rename rename-marks rename-new rename-old subst-rename? wrap-subst wrap-marks make-wrap id-sym-name&marks id-sym-name id? nonsymbol-id? global-extend lookup macros-only-env extend-var-env extend-env null-env binding-value binding-type make-binding arg-check source-annotation no-source unannotate set-syntax-object-wrap! set-syntax-object-expression! syntax-object-wrap syntax-object-expression syntax-object? make-syntax-object build-lexical-var build-letrec build-named-let build-let build-sequence build-data build-primref build-lambda build-global-definition build-global-assignment build-global-reference build-lexical-assignment build-lexical-reference build-conditional build-application build-annotated get-global-definition-hook put-global-definition-hook gensym-hook error-hook local-eval-hook top-level-eval-hook fx< fx= fx- fx+ noexpand) ((top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top)) ("i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i")) #(ribcage (define-structure) ((top)) ("i")))))) (quote (())) syntmp-s-776)) syntmp-tmp-807) (syntax-error syntmp-tmp-787))) (syntax-dispatch syntmp-tmp-787 (quote (any any)))))) (syntax-dispatch syntmp-tmp-787 (quote (any (any . any) any . each-any)))))) (syntax-dispatch syntmp-tmp-787 (quote (any any any))))) syntmp-e-773) (if (memv syntmp-t-786 (quote (define-syntax))) ((lambda (syntmp-tmp-812) ((lambda (syntmp-tmp-813) (if (if syntmp-tmp-813 (apply (lambda (syntmp-_-814 syntmp-name-815 syntmp-val-816) (syntmp-id?-102 syntmp-name-815)) syntmp-tmp-813) #f) (apply (lambda (syntmp-_-817 syntmp-name-818 syntmp-val-819) (values (quote define-syntax-form) syntmp-name-818 syntmp-val-819 syntmp-w-775 syntmp-s-776)) syntmp-tmp-813) (syntax-error syntmp-tmp-812))) (syntax-dispatch syntmp-tmp-812 (quote (any any any))))) syntmp-e-773) (values (quote call) #f syntmp-e-773 syntmp-w-775 syntmp-s-776)))))))))))))) (values (quote call) #f syntmp-e-773 syntmp-w-775 syntmp-s-776)))) ((syntmp-syntax-object?-88 syntmp-e-773) (syntmp-syntax-type-136 (syntmp-syntax-object-expression-89 syntmp-e-773) syntmp-r-774 (syntmp-join-wraps-121 syntmp-w-775 (syntmp-syntax-object-wrap-90 syntmp-e-773)) #f syntmp-rib-777)) ((annotation? syntmp-e-773) (syntmp-syntax-type-136 (annotation-expression syntmp-e-773) syntmp-r-774 syntmp-w-775 (annotation-source syntmp-e-773) syntmp-rib-777)) ((self-evaluating? syntmp-e-773) (values (quote constant) #f syntmp-e-773 syntmp-w-775 syntmp-s-776)) (else (values (quote other) #f syntmp-e-773 syntmp-w-775 syntmp-s-776))))) (syntmp-chi-when-list-135 (lambda (syntmp-e-820 syntmp-when-list-821 syntmp-w-822) (let syntmp-f-823 ((syntmp-when-list-824 syntmp-when-list-821) (syntmp-situations-825 (quote ()))) (if (null? syntmp-when-list-824) syntmp-situations-825 (syntmp-f-823 (cdr syntmp-when-list-824) (cons (let ((syntmp-x-826 (car syntmp-when-list-824))) (cond ((syntmp-free-id=?-125 syntmp-x-826 (quote #(syntax-object compile ((top) #(ribcage () () ()) #(ribcage #(x) #((top)) #("i")) #(ribcage () () ()) #(ribcage #(f when-list situations) #((top) (top) (top)) #("i" "i" "i")) #(ribcage () () ()) #(ribcage #(e when-list w) #((top) (top) (top)) #("i" "i" "i")) #(ribcage (lambda-var-list gen-var strip strip-annotation ellipsis? chi-void eval-local-transformer chi-local-syntax chi-lambda-clause chi-body chi-macro chi-application chi-expr chi chi-top syntax-type chi-when-list chi-install-global chi-top-sequence chi-sequence source-wrap wrap bound-id-member? distinct-bound-ids? valid-bound-ids? bound-id=? free-id=? id-var-name same-marks? join-marks join-wraps smart-append make-binding-wrap extend-ribcage! make-empty-ribcage new-mark anti-mark the-anti-mark top-marked? top-wrap empty-wrap set-ribcage-labels! set-ribcage-marks! set-ribcage-symnames! ribcage-labels ribcage-marks ribcage-symnames ribcage? make-ribcage gen-labels gen-label make-rename rename-marks rename-new rename-old subst-rename? wrap-subst wrap-marks make-wrap id-sym-name&marks id-sym-name id? nonsymbol-id? global-extend lookup macros-only-env extend-var-env extend-env null-env binding-value binding-type make-binding arg-check source-annotation no-source unannotate set-syntax-object-wrap! set-syntax-object-expression! syntax-object-wrap syntax-object-expression syntax-object? make-syntax-object build-lexical-var build-letrec build-named-let build-let build-sequence build-data build-primref build-lambda build-global-definition build-global-assignment build-global-reference build-lexical-assignment build-lexical-reference build-conditional build-application build-annotated get-global-definition-hook put-global-definition-hook gensym-hook error-hook local-eval-hook top-level-eval-hook fx< fx= fx- fx+ noexpand) ((top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top)) ("i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i")) #(ribcage (define-structure) ((top)) ("i")))))) (quote compile)) ((syntmp-free-id=?-125 syntmp-x-826 (quote #(syntax-object load ((top) #(ribcage () () ()) #(ribcage #(x) #((top)) #("i")) #(ribcage () () ()) #(ribcage #(f when-list situations) #((top) (top) (top)) #("i" "i" "i")) #(ribcage () () ()) #(ribcage #(e when-list w) #((top) (top) (top)) #("i" "i" "i")) #(ribcage (lambda-var-list gen-var strip strip-annotation ellipsis? chi-void eval-local-transformer chi-local-syntax chi-lambda-clause chi-body chi-macro chi-application chi-expr chi chi-top syntax-type chi-when-list chi-install-global chi-top-sequence chi-sequence source-wrap wrap bound-id-member? distinct-bound-ids? valid-bound-ids? bound-id=? free-id=? id-var-name same-marks? join-marks join-wraps smart-append make-binding-wrap extend-ribcage! make-empty-ribcage new-mark anti-mark the-anti-mark top-marked? top-wrap empty-wrap set-ribcage-labels! set-ribcage-marks! set-ribcage-symnames! ribcage-labels ribcage-marks ribcage-symnames ribcage? make-ribcage gen-labels gen-label make-rename rename-marks rename-new rename-old subst-rename? wrap-subst wrap-marks make-wrap id-sym-name&marks id-sym-name id? nonsymbol-id? global-extend lookup macros-only-env extend-var-env extend-env null-env binding-value binding-type make-binding arg-check source-annotation no-source unannotate set-syntax-object-wrap! set-syntax-object-expression! syntax-object-wrap syntax-object-expression syntax-object? make-syntax-object build-lexical-var build-letrec build-named-let build-let build-sequence build-data build-primref build-lambda build-global-definition build-global-assignment build-global-reference build-lexical-assignment build-lexical-reference build-conditional build-application build-annotated get-global-definition-hook put-global-definition-hook gensym-hook error-hook local-eval-hook top-level-eval-hook fx< fx= fx- fx+ noexpand) ((top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top)) ("i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i")) #(ribcage (define-structure) ((top)) ("i")))))) (quote load)) ((syntmp-free-id=?-125 syntmp-x-826 (quote #(syntax-object eval ((top) #(ribcage () () ()) #(ribcage #(x) #((top)) #("i")) #(ribcage () () ()) #(ribcage #(f when-list situations) #((top) (top) (top)) #("i" "i" "i")) #(ribcage () () ()) #(ribcage #(e when-list w) #((top) (top) (top)) #("i" "i" "i")) #(ribcage (lambda-var-list gen-var strip strip-annotation ellipsis? chi-void eval-local-transformer chi-local-syntax chi-lambda-clause chi-body chi-macro chi-application chi-expr chi chi-top syntax-type chi-when-list chi-install-global chi-top-sequence chi-sequence source-wrap wrap bound-id-member? distinct-bound-ids? valid-bound-ids? bound-id=? free-id=? id-var-name same-marks? join-marks join-wraps smart-append make-binding-wrap extend-ribcage! make-empty-ribcage new-mark anti-mark the-anti-mark top-marked? top-wrap empty-wrap set-ribcage-labels! set-ribcage-marks! set-ribcage-symnames! ribcage-labels ribcage-marks ribcage-symnames ribcage? make-ribcage gen-labels gen-label make-rename rename-marks rename-new rename-old subst-rename? wrap-subst wrap-marks make-wrap id-sym-name&marks id-sym-name id? nonsymbol-id? global-extend lookup macros-only-env extend-var-env extend-env null-env binding-value binding-type make-binding arg-check source-annotation no-source unannotate set-syntax-object-wrap! set-syntax-object-expression! syntax-object-wrap syntax-object-expression syntax-object? make-syntax-object build-lexical-var build-letrec build-named-let build-let build-sequence build-data build-primref build-lambda build-global-definition build-global-assignment build-global-reference build-lexical-assignment build-lexical-reference build-conditional build-application build-annotated get-global-definition-hook put-global-definition-hook gensym-hook error-hook local-eval-hook top-level-eval-hook fx< fx= fx- fx+ noexpand) ((top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top)) ("i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i")) #(ribcage (define-structure) ((top)) ("i")))))) (quote eval)) (else (syntax-error (syntmp-wrap-130 syntmp-x-826 syntmp-w-822) "invalid eval-when situation")))) syntmp-situations-825)))))) (syntmp-chi-install-global-134 (lambda (syntmp-name-827 syntmp-e-828) (syntmp-build-annotated-81 #f (list (syntmp-build-annotated-81 #f (quote install-global-transformer)) (syntmp-build-data-82 #f syntmp-name-827) syntmp-e-828)))) (syntmp-chi-top-sequence-133 (lambda (syntmp-body-829 syntmp-r-830 syntmp-w-831 syntmp-s-832 syntmp-m-833 syntmp-esew-834) (syntmp-build-sequence-83 syntmp-s-832 (let syntmp-dobody-835 ((syntmp-body-836 syntmp-body-829) (syntmp-r-837 syntmp-r-830) (syntmp-w-838 syntmp-w-831) (syntmp-m-839 syntmp-m-833) (syntmp-esew-840 syntmp-esew-834)) (if (null? syntmp-body-836) (quote ()) (let ((syntmp-first-841 (syntmp-chi-top-137 (car syntmp-body-836) syntmp-r-837 syntmp-w-838 syntmp-m-839 syntmp-esew-840))) (cons syntmp-first-841 (syntmp-dobody-835 (cdr syntmp-body-836) syntmp-r-837 syntmp-w-838 syntmp-m-839 syntmp-esew-840)))))))) (syntmp-chi-sequence-132 (lambda (syntmp-body-842 syntmp-r-843 syntmp-w-844 syntmp-s-845) (syntmp-build-sequence-83 syntmp-s-845 (let syntmp-dobody-846 ((syntmp-body-847 syntmp-body-842) (syntmp-r-848 syntmp-r-843) (syntmp-w-849 syntmp-w-844)) (if (null? syntmp-body-847) (quote ()) (let ((syntmp-first-850 (syntmp-chi-138 (car syntmp-body-847) syntmp-r-848 syntmp-w-849))) (cons syntmp-first-850 (syntmp-dobody-846 (cdr syntmp-body-847) syntmp-r-848 syntmp-w-849)))))))) (syntmp-source-wrap-131 (lambda (syntmp-x-851 syntmp-w-852 syntmp-s-853) (syntmp-wrap-130 (if syntmp-s-853 (make-annotation syntmp-x-851 syntmp-s-853 #f) syntmp-x-851) syntmp-w-852))) (syntmp-wrap-130 (lambda (syntmp-x-854 syntmp-w-855) (cond ((and (null? (syntmp-wrap-marks-105 syntmp-w-855)) (null? (syntmp-wrap-subst-106 syntmp-w-855))) syntmp-x-854) ((syntmp-syntax-object?-88 syntmp-x-854) (syntmp-make-syntax-object-87 (syntmp-syntax-object-expression-89 syntmp-x-854) (syntmp-join-wraps-121 syntmp-w-855 (syntmp-syntax-object-wrap-90 syntmp-x-854)))) ((null? syntmp-x-854) syntmp-x-854) (else (syntmp-make-syntax-object-87 syntmp-x-854 syntmp-w-855))))) (syntmp-bound-id-member?-129 (lambda (syntmp-x-856 syntmp-list-857) (and (not (null? syntmp-list-857)) (or (syntmp-bound-id=?-126 syntmp-x-856 (car syntmp-list-857)) (syntmp-bound-id-member?-129 syntmp-x-856 (cdr syntmp-list-857)))))) (syntmp-distinct-bound-ids?-128 (lambda (syntmp-ids-858) (let syntmp-distinct?-859 ((syntmp-ids-860 syntmp-ids-858)) (or (null? syntmp-ids-860) (and (not (syntmp-bound-id-member?-129 (car syntmp-ids-860) (cdr syntmp-ids-860))) (syntmp-distinct?-859 (cdr syntmp-ids-860))))))) (syntmp-valid-bound-ids?-127 (lambda (syntmp-ids-861) (and (let syntmp-all-ids?-862 ((syntmp-ids-863 syntmp-ids-861)) (or (null? syntmp-ids-863) (and (syntmp-id?-102 (car syntmp-ids-863)) (syntmp-all-ids?-862 (cdr syntmp-ids-863))))) (syntmp-distinct-bound-ids?-128 syntmp-ids-861)))) (syntmp-bound-id=?-126 (lambda (syntmp-i-864 syntmp-j-865) (if (and (syntmp-syntax-object?-88 syntmp-i-864) (syntmp-syntax-object?-88 syntmp-j-865)) (and (eq? (let ((syntmp-e-866 (syntmp-syntax-object-expression-89 syntmp-i-864))) (if (annotation? syntmp-e-866) (annotation-expression syntmp-e-866) syntmp-e-866)) (let ((syntmp-e-867 (syntmp-syntax-object-expression-89 syntmp-j-865))) (if (annotation? syntmp-e-867) (annotation-expression syntmp-e-867) syntmp-e-867))) (syntmp-same-marks?-123 (syntmp-wrap-marks-105 (syntmp-syntax-object-wrap-90 syntmp-i-864)) (syntmp-wrap-marks-105 (syntmp-syntax-object-wrap-90 syntmp-j-865)))) (eq? (let ((syntmp-e-868 syntmp-i-864)) (if (annotation? syntmp-e-868) (annotation-expression syntmp-e-868) syntmp-e-868)) (let ((syntmp-e-869 syntmp-j-865)) (if (annotation? syntmp-e-869) (annotation-expression syntmp-e-869) syntmp-e-869)))))) (syntmp-free-id=?-125 (lambda (syntmp-i-870 syntmp-j-871) (and (eq? (let ((syntmp-x-872 syntmp-i-870)) (let ((syntmp-e-873 (if (syntmp-syntax-object?-88 syntmp-x-872) (syntmp-syntax-object-expression-89 syntmp-x-872) syntmp-x-872))) (if (annotation? syntmp-e-873) (annotation-expression syntmp-e-873) syntmp-e-873))) (let ((syntmp-x-874 syntmp-j-871)) (let ((syntmp-e-875 (if (syntmp-syntax-object?-88 syntmp-x-874) (syntmp-syntax-object-expression-89 syntmp-x-874) syntmp-x-874))) (if (annotation? syntmp-e-875) (annotation-expression syntmp-e-875) syntmp-e-875)))) (eq? (syntmp-id-var-name-124 syntmp-i-870 (quote (()))) (syntmp-id-var-name-124 syntmp-j-871 (quote (()))))))) (syntmp-id-var-name-124 (lambda (syntmp-id-876 syntmp-w-877) (letrec ((syntmp-search-vector-rib-880 (lambda (syntmp-sym-891 syntmp-subst-892 syntmp-marks-893 syntmp-symnames-894 syntmp-ribcage-895) (let ((syntmp-n-896 (vector-length syntmp-symnames-894))) (let syntmp-f-897 ((syntmp-i-898 0)) (cond ((syntmp-fx=-74 syntmp-i-898 syntmp-n-896) (syntmp-search-878 syntmp-sym-891 (cdr syntmp-subst-892) syntmp-marks-893)) ((and (eq? (vector-ref syntmp-symnames-894 syntmp-i-898) syntmp-sym-891) (syntmp-same-marks?-123 syntmp-marks-893 (vector-ref (syntmp-ribcage-marks-112 syntmp-ribcage-895) syntmp-i-898))) (values (vector-ref (syntmp-ribcage-labels-113 syntmp-ribcage-895) syntmp-i-898) syntmp-marks-893)) (else (syntmp-f-897 (syntmp-fx+-72 syntmp-i-898 1)))))))) (syntmp-search-list-rib-879 (lambda (syntmp-sym-899 syntmp-subst-900 syntmp-marks-901 syntmp-symnames-902 syntmp-ribcage-903) (let syntmp-f-904 ((syntmp-symnames-905 syntmp-symnames-902) (syntmp-i-906 0)) (cond ((null? syntmp-symnames-905) (syntmp-search-878 syntmp-sym-899 (cdr syntmp-subst-900) syntmp-marks-901)) ((and (eq? (car syntmp-symnames-905) syntmp-sym-899) (syntmp-same-marks?-123 syntmp-marks-901 (list-ref (syntmp-ribcage-marks-112 syntmp-ribcage-903) syntmp-i-906))) (values (list-ref (syntmp-ribcage-labels-113 syntmp-ribcage-903) syntmp-i-906) syntmp-marks-901)) (else (syntmp-f-904 (cdr syntmp-symnames-905) (syntmp-fx+-72 syntmp-i-906 1))))))) (syntmp-search-878 (lambda (syntmp-sym-907 syntmp-subst-908 syntmp-marks-909) (if (null? syntmp-subst-908) (values #f syntmp-marks-909) (let ((syntmp-fst-910 (car syntmp-subst-908))) (if (eq? syntmp-fst-910 (quote shift)) (syntmp-search-878 syntmp-sym-907 (cdr syntmp-subst-908) (cdr syntmp-marks-909)) (let ((syntmp-symnames-911 (syntmp-ribcage-symnames-111 syntmp-fst-910))) (if (vector? syntmp-symnames-911) (syntmp-search-vector-rib-880 syntmp-sym-907 syntmp-subst-908 syntmp-marks-909 syntmp-symnames-911 syntmp-fst-910) (syntmp-search-list-rib-879 syntmp-sym-907 syntmp-subst-908 syntmp-marks-909 syntmp-symnames-911 syntmp-fst-910))))))))) (cond ((symbol? syntmp-id-876) (or (call-with-values (lambda () (syntmp-search-878 syntmp-id-876 (syntmp-wrap-subst-106 syntmp-w-877) (syntmp-wrap-marks-105 syntmp-w-877))) (lambda (syntmp-x-913 . syntmp-ignore-912) syntmp-x-913)) syntmp-id-876)) ((syntmp-syntax-object?-88 syntmp-id-876) (let ((syntmp-id-914 (let ((syntmp-e-916 (syntmp-syntax-object-expression-89 syntmp-id-876))) (if (annotation? syntmp-e-916) (annotation-expression syntmp-e-916) syntmp-e-916))) (syntmp-w1-915 (syntmp-syntax-object-wrap-90 syntmp-id-876))) (let ((syntmp-marks-917 (syntmp-join-marks-122 (syntmp-wrap-marks-105 syntmp-w-877) (syntmp-wrap-marks-105 syntmp-w1-915)))) (call-with-values (lambda () (syntmp-search-878 syntmp-id-914 (syntmp-wrap-subst-106 syntmp-w-877) syntmp-marks-917)) (lambda (syntmp-new-id-918 syntmp-marks-919) (or syntmp-new-id-918 (call-with-values (lambda () (syntmp-search-878 syntmp-id-914 (syntmp-wrap-subst-106 syntmp-w1-915) syntmp-marks-919)) (lambda (syntmp-x-921 . syntmp-ignore-920) syntmp-x-921)) syntmp-id-914)))))) ((annotation? syntmp-id-876) (let ((syntmp-id-922 (let ((syntmp-e-923 syntmp-id-876)) (if (annotation? syntmp-e-923) (annotation-expression syntmp-e-923) syntmp-e-923)))) (or (call-with-values (lambda () (syntmp-search-878 syntmp-id-922 (syntmp-wrap-subst-106 syntmp-w-877) (syntmp-wrap-marks-105 syntmp-w-877))) (lambda (syntmp-x-925 . syntmp-ignore-924) syntmp-x-925)) syntmp-id-922))) (else (syntmp-error-hook-78 (quote id-var-name) "invalid id" syntmp-id-876)))))) (syntmp-same-marks?-123 (lambda (syntmp-x-926 syntmp-y-927) (or (eq? syntmp-x-926 syntmp-y-927) (and (not (null? syntmp-x-926)) (not (null? syntmp-y-927)) (eq? (car syntmp-x-926) (car syntmp-y-927)) (syntmp-same-marks?-123 (cdr syntmp-x-926) (cdr syntmp-y-927)))))) (syntmp-join-marks-122 (lambda (syntmp-m1-928 syntmp-m2-929) (syntmp-smart-append-120 syntmp-m1-928 syntmp-m2-929))) (syntmp-join-wraps-121 (lambda (syntmp-w1-930 syntmp-w2-931) (let ((syntmp-m1-932 (syntmp-wrap-marks-105 syntmp-w1-930)) (syntmp-s1-933 (syntmp-wrap-subst-106 syntmp-w1-930))) (if (null? syntmp-m1-932) (if (null? syntmp-s1-933) syntmp-w2-931 (syntmp-make-wrap-104 (syntmp-wrap-marks-105 syntmp-w2-931) (syntmp-smart-append-120 syntmp-s1-933 (syntmp-wrap-subst-106 syntmp-w2-931)))) (syntmp-make-wrap-104 (syntmp-smart-append-120 syntmp-m1-932 (syntmp-wrap-marks-105 syntmp-w2-931)) (syntmp-smart-append-120 syntmp-s1-933 (syntmp-wrap-subst-106 syntmp-w2-931))))))) (syntmp-smart-append-120 (lambda (syntmp-m1-934 syntmp-m2-935) (if (null? syntmp-m2-935) syntmp-m1-934 (append syntmp-m1-934 syntmp-m2-935)))) (syntmp-make-binding-wrap-119 (lambda (syntmp-ids-936 syntmp-labels-937 syntmp-w-938) (if (null? syntmp-ids-936) syntmp-w-938 (syntmp-make-wrap-104 (syntmp-wrap-marks-105 syntmp-w-938) (cons (let ((syntmp-labelvec-939 (list->vector syntmp-labels-937))) (let ((syntmp-n-940 (vector-length syntmp-labelvec-939))) (let ((syntmp-symnamevec-941 (make-vector syntmp-n-940)) (syntmp-marksvec-942 (make-vector syntmp-n-940))) (begin (let syntmp-f-943 ((syntmp-ids-944 syntmp-ids-936) (syntmp-i-945 0)) (if (not (null? syntmp-ids-944)) (call-with-values (lambda () (syntmp-id-sym-name&marks-103 (car syntmp-ids-944) syntmp-w-938)) (lambda (syntmp-symname-946 syntmp-marks-947) (begin (vector-set! syntmp-symnamevec-941 syntmp-i-945 syntmp-symname-946) (vector-set! syntmp-marksvec-942 syntmp-i-945 syntmp-marks-947) (syntmp-f-943 (cdr syntmp-ids-944) (syntmp-fx+-72 syntmp-i-945 1))))))) (syntmp-make-ribcage-109 syntmp-symnamevec-941 syntmp-marksvec-942 syntmp-labelvec-939))))) (syntmp-wrap-subst-106 syntmp-w-938)))))) (syntmp-extend-ribcage!-118 (lambda (syntmp-ribcage-948 syntmp-id-949 syntmp-label-950) (begin (syntmp-set-ribcage-symnames!-114 syntmp-ribcage-948 (cons (let ((syntmp-e-951 (syntmp-syntax-object-expression-89 syntmp-id-949))) (if (annotation? syntmp-e-951) (annotation-expression syntmp-e-951) syntmp-e-951)) (syntmp-ribcage-symnames-111 syntmp-ribcage-948))) (syntmp-set-ribcage-marks!-115 syntmp-ribcage-948 (cons (syntmp-wrap-marks-105 (syntmp-syntax-object-wrap-90 syntmp-id-949)) (syntmp-ribcage-marks-112 syntmp-ribcage-948))) (syntmp-set-ribcage-labels!-116 syntmp-ribcage-948 (cons syntmp-label-950 (syntmp-ribcage-labels-113 syntmp-ribcage-948)))))) (syntmp-anti-mark-117 (lambda (syntmp-w-952) (syntmp-make-wrap-104 (cons #f (syntmp-wrap-marks-105 syntmp-w-952)) (cons (quote shift) (syntmp-wrap-subst-106 syntmp-w-952))))) (syntmp-set-ribcage-labels!-116 (lambda (syntmp-x-953 syntmp-update-954) (vector-set! syntmp-x-953 3 syntmp-update-954))) (syntmp-set-ribcage-marks!-115 (lambda (syntmp-x-955 syntmp-update-956) (vector-set! syntmp-x-955 2 syntmp-update-956))) (syntmp-set-ribcage-symnames!-114 (lambda (syntmp-x-957 syntmp-update-958) (vector-set! syntmp-x-957 1 syntmp-update-958))) (syntmp-ribcage-labels-113 (lambda (syntmp-x-959) (vector-ref syntmp-x-959 3))) (syntmp-ribcage-marks-112 (lambda (syntmp-x-960) (vector-ref syntmp-x-960 2))) (syntmp-ribcage-symnames-111 (lambda (syntmp-x-961) (vector-ref syntmp-x-961 1))) (syntmp-ribcage?-110 (lambda (syntmp-x-962) (and (vector? syntmp-x-962) (= (vector-length syntmp-x-962) 4) (eq? (vector-ref syntmp-x-962 0) (quote ribcage))))) (syntmp-make-ribcage-109 (lambda (syntmp-symnames-963 syntmp-marks-964 syntmp-labels-965) (vector (quote ribcage) syntmp-symnames-963 syntmp-marks-964 syntmp-labels-965))) (syntmp-gen-labels-108 (lambda (syntmp-ls-966) (if (null? syntmp-ls-966) (quote ()) (cons (syntmp-gen-label-107) (syntmp-gen-labels-108 (cdr syntmp-ls-966)))))) (syntmp-gen-label-107 (lambda () (string #\i))) (syntmp-wrap-subst-106 cdr) (syntmp-wrap-marks-105 car) (syntmp-make-wrap-104 cons) (syntmp-id-sym-name&marks-103 (lambda (syntmp-x-967 syntmp-w-968) (if (syntmp-syntax-object?-88 syntmp-x-967) (values (let ((syntmp-e-969 (syntmp-syntax-object-expression-89 syntmp-x-967))) (if (annotation? syntmp-e-969) (annotation-expression syntmp-e-969) syntmp-e-969)) (syntmp-join-marks-122 (syntmp-wrap-marks-105 syntmp-w-968) (syntmp-wrap-marks-105 (syntmp-syntax-object-wrap-90 syntmp-x-967)))) (values (let ((syntmp-e-970 syntmp-x-967)) (if (annotation? syntmp-e-970) (annotation-expression syntmp-e-970) syntmp-e-970)) (syntmp-wrap-marks-105 syntmp-w-968))))) (syntmp-id?-102 (lambda (syntmp-x-971) (cond ((symbol? syntmp-x-971) #t) ((syntmp-syntax-object?-88 syntmp-x-971) (symbol? (let ((syntmp-e-972 (syntmp-syntax-object-expression-89 syntmp-x-971))) (if (annotation? syntmp-e-972) (annotation-expression syntmp-e-972) syntmp-e-972)))) ((annotation? syntmp-x-971) (symbol? (annotation-expression syntmp-x-971))) (else #f)))) (syntmp-nonsymbol-id?-101 (lambda (syntmp-x-973) (and (syntmp-syntax-object?-88 syntmp-x-973) (symbol? (let ((syntmp-e-974 (syntmp-syntax-object-expression-89 syntmp-x-973))) (if (annotation? syntmp-e-974) (annotation-expression syntmp-e-974) syntmp-e-974)))))) (syntmp-global-extend-100 (lambda (syntmp-type-975 syntmp-sym-976 syntmp-val-977) (syntmp-put-global-definition-hook-79 syntmp-sym-976 (cons syntmp-type-975 syntmp-val-977)))) (syntmp-lookup-99 (lambda (syntmp-x-978 syntmp-r-979) (cond ((assq syntmp-x-978 syntmp-r-979) => cdr) ((symbol? syntmp-x-978) (or (syntmp-get-global-definition-hook-80 syntmp-x-978) (quote (global)))) (else (quote (displaced-lexical)))))) (syntmp-macros-only-env-98 (lambda (syntmp-r-980) (if (null? syntmp-r-980) (quote ()) (let ((syntmp-a-981 (car syntmp-r-980))) (if (eq? (cadr syntmp-a-981) (quote macro)) (cons syntmp-a-981 (syntmp-macros-only-env-98 (cdr syntmp-r-980))) (syntmp-macros-only-env-98 (cdr syntmp-r-980))))))) (syntmp-extend-var-env-97 (lambda (syntmp-labels-982 syntmp-vars-983 syntmp-r-984) (if (null? syntmp-labels-982) syntmp-r-984 (syntmp-extend-var-env-97 (cdr syntmp-labels-982) (cdr syntmp-vars-983) (cons (cons (car syntmp-labels-982) (cons (quote lexical) (car syntmp-vars-983))) syntmp-r-984))))) (syntmp-extend-env-96 (lambda (syntmp-labels-985 syntmp-bindings-986 syntmp-r-987) (if (null? syntmp-labels-985) syntmp-r-987 (syntmp-extend-env-96 (cdr syntmp-labels-985) (cdr syntmp-bindings-986) (cons (cons (car syntmp-labels-985) (car syntmp-bindings-986)) syntmp-r-987))))) (syntmp-binding-value-95 cdr) (syntmp-binding-type-94 car) (syntmp-source-annotation-93 (lambda (syntmp-x-988) (cond ((annotation? syntmp-x-988) (annotation-source syntmp-x-988)) ((syntmp-syntax-object?-88 syntmp-x-988) (syntmp-source-annotation-93 (syntmp-syntax-object-expression-89 syntmp-x-988))) (else #f)))) (syntmp-set-syntax-object-wrap!-92 (lambda (syntmp-x-989 syntmp-update-990) (vector-set! syntmp-x-989 2 syntmp-update-990))) (syntmp-set-syntax-object-expression!-91 (lambda (syntmp-x-991 syntmp-update-992) (vector-set! syntmp-x-991 1 syntmp-update-992))) (syntmp-syntax-object-wrap-90 (lambda (syntmp-x-993) (vector-ref syntmp-x-993 2))) (syntmp-syntax-object-expression-89 (lambda (syntmp-x-994) (vector-ref syntmp-x-994 1))) (syntmp-syntax-object?-88 (lambda (syntmp-x-995) (and (vector? syntmp-x-995) (= (vector-length syntmp-x-995) 3) (eq? (vector-ref syntmp-x-995 0) (quote syntax-object))))) (syntmp-make-syntax-object-87 (lambda (syntmp-expression-996 syntmp-wrap-997) (vector (quote syntax-object) syntmp-expression-996 syntmp-wrap-997))) (syntmp-build-letrec-86 (lambda (syntmp-src-998 syntmp-vars-999 syntmp-val-exps-1000 syntmp-body-exp-1001) (if (null? syntmp-vars-999) (syntmp-build-annotated-81 syntmp-src-998 syntmp-body-exp-1001) (syntmp-build-annotated-81 syntmp-src-998 (list (quote letrec) (map list syntmp-vars-999 syntmp-val-exps-1000) syntmp-body-exp-1001))))) (syntmp-build-named-let-85 (lambda (syntmp-src-1002 syntmp-vars-1003 syntmp-val-exps-1004 syntmp-body-exp-1005) (if (null? syntmp-vars-1003) (syntmp-build-annotated-81 syntmp-src-1002 syntmp-body-exp-1005) (syntmp-build-annotated-81 syntmp-src-1002 (list (quote let) (car syntmp-vars-1003) (map list (cdr syntmp-vars-1003) syntmp-val-exps-1004) syntmp-body-exp-1005))))) (syntmp-build-let-84 (lambda (syntmp-src-1006 syntmp-vars-1007 syntmp-val-exps-1008 syntmp-body-exp-1009) (if (null? syntmp-vars-1007) (syntmp-build-annotated-81 syntmp-src-1006 syntmp-body-exp-1009) (syntmp-build-annotated-81 syntmp-src-1006 (list (quote let) (map list syntmp-vars-1007 syntmp-val-exps-1008) syntmp-body-exp-1009))))) (syntmp-build-sequence-83 (lambda (syntmp-src-1010 syntmp-exps-1011) (if (null? (cdr syntmp-exps-1011)) (syntmp-build-annotated-81 syntmp-src-1010 (car syntmp-exps-1011)) (syntmp-build-annotated-81 syntmp-src-1010 (cons (quote begin) syntmp-exps-1011))))) (syntmp-build-data-82 (lambda (syntmp-src-1012 syntmp-exp-1013) (if (and (self-evaluating? syntmp-exp-1013) (not (vector? syntmp-exp-1013))) (syntmp-build-annotated-81 syntmp-src-1012 syntmp-exp-1013) (syntmp-build-annotated-81 syntmp-src-1012 (list (quote quote) syntmp-exp-1013))))) (syntmp-build-annotated-81 (lambda (syntmp-src-1014 syntmp-exp-1015) (if (and syntmp-src-1014 (not (annotation? syntmp-exp-1015))) (make-annotation syntmp-exp-1015 syntmp-src-1014 #t) syntmp-exp-1015))) (syntmp-get-global-definition-hook-80 (lambda (syntmp-symbol-1016) (getprop syntmp-symbol-1016 (quote *sc-expander*)))) (syntmp-put-global-definition-hook-79 (lambda (syntmp-symbol-1017 syntmp-binding-1018) (putprop syntmp-symbol-1017 (quote *sc-expander*) syntmp-binding-1018))) (syntmp-error-hook-78 (lambda (syntmp-who-1019 syntmp-why-1020 syntmp-what-1021) (error syntmp-who-1019 "~a ~s" syntmp-why-1020 syntmp-what-1021))) (syntmp-local-eval-hook-77 (lambda (syntmp-x-1022) (eval (list syntmp-noexpand-71 syntmp-x-1022) (interaction-environment)))) (syntmp-top-level-eval-hook-76 (lambda (syntmp-x-1023) (eval (list syntmp-noexpand-71 syntmp-x-1023) (interaction-environment)))) (syntmp-fx<-75 <) (syntmp-fx=-74 =) (syntmp-fx--73 -) (syntmp-fx+-72 +) (syntmp-noexpand-71 "noexpand")) (begin (syntmp-global-extend-100 (quote local-syntax) (quote letrec-syntax) #t) (syntmp-global-extend-100 (quote local-syntax) (quote let-syntax) #f) (syntmp-global-extend-100 (quote core) (quote fluid-let-syntax) (lambda (syntmp-e-1024 syntmp-r-1025 syntmp-w-1026 syntmp-s-1027) ((lambda (syntmp-tmp-1028) ((lambda (syntmp-tmp-1029) (if (if syntmp-tmp-1029 (apply (lambda (syntmp-_-1030 syntmp-var-1031 syntmp-val-1032 syntmp-e1-1033 syntmp-e2-1034) (syntmp-valid-bound-ids?-127 syntmp-var-1031)) syntmp-tmp-1029) #f) (apply (lambda (syntmp-_-1036 syntmp-var-1037 syntmp-val-1038 syntmp-e1-1039 syntmp-e2-1040) (let ((syntmp-names-1041 (map (lambda (syntmp-x-1042) (syntmp-id-var-name-124 syntmp-x-1042 syntmp-w-1026)) syntmp-var-1037))) (begin (for-each (lambda (syntmp-id-1044 syntmp-n-1045) (let ((syntmp-t-1046 (syntmp-binding-type-94 (syntmp-lookup-99 syntmp-n-1045 syntmp-r-1025)))) (if (memv syntmp-t-1046 (quote (displaced-lexical))) (syntax-error (syntmp-source-wrap-131 syntmp-id-1044 syntmp-w-1026 syntmp-s-1027) "identifier out of context")))) syntmp-var-1037 syntmp-names-1041) (syntmp-chi-body-142 (cons syntmp-e1-1039 syntmp-e2-1040) (syntmp-source-wrap-131 syntmp-e-1024 syntmp-w-1026 syntmp-s-1027) (syntmp-extend-env-96 syntmp-names-1041 (let ((syntmp-trans-r-1049 (syntmp-macros-only-env-98 syntmp-r-1025))) (map (lambda (syntmp-x-1050) (cons (quote macro) (syntmp-eval-local-transformer-145 (syntmp-chi-138 syntmp-x-1050 syntmp-trans-r-1049 syntmp-w-1026)))) syntmp-val-1038)) syntmp-r-1025) syntmp-w-1026)))) syntmp-tmp-1029) ((lambda (syntmp-_-1052) (syntax-error (syntmp-source-wrap-131 syntmp-e-1024 syntmp-w-1026 syntmp-s-1027))) syntmp-tmp-1028))) (syntax-dispatch syntmp-tmp-1028 (quote (any #(each (any any)) any . each-any))))) syntmp-e-1024))) (syntmp-global-extend-100 (quote core) (quote quote) (lambda (syntmp-e-1053 syntmp-r-1054 syntmp-w-1055 syntmp-s-1056) ((lambda (syntmp-tmp-1057) ((lambda (syntmp-tmp-1058) (if syntmp-tmp-1058 (apply (lambda (syntmp-_-1059 syntmp-e-1060) (syntmp-build-data-82 syntmp-s-1056 (syntmp-strip-149 syntmp-e-1060 syntmp-w-1055))) syntmp-tmp-1058) ((lambda (syntmp-_-1061) (syntax-error (syntmp-source-wrap-131 syntmp-e-1053 syntmp-w-1055 syntmp-s-1056))) syntmp-tmp-1057))) (syntax-dispatch syntmp-tmp-1057 (quote (any any))))) syntmp-e-1053))) (syntmp-global-extend-100 (quote core) (quote syntax) (letrec ((syntmp-regen-1069 (lambda (syntmp-x-1070) (let ((syntmp-t-1071 (car syntmp-x-1070))) (if (memv syntmp-t-1071 (quote (ref))) (syntmp-build-annotated-81 #f (cadr syntmp-x-1070)) (if (memv syntmp-t-1071 (quote (primitive))) (syntmp-build-annotated-81 #f (cadr syntmp-x-1070)) (if (memv syntmp-t-1071 (quote (quote))) (syntmp-build-data-82 #f (cadr syntmp-x-1070)) (if (memv syntmp-t-1071 (quote (lambda))) (syntmp-build-annotated-81 #f (list (quote lambda) (cadr syntmp-x-1070) (syntmp-regen-1069 (caddr syntmp-x-1070)))) (if (memv syntmp-t-1071 (quote (map))) (let ((syntmp-ls-1072 (map syntmp-regen-1069 (cdr syntmp-x-1070)))) (syntmp-build-annotated-81 #f (cons (if (syntmp-fx=-74 (length syntmp-ls-1072) 2) (syntmp-build-annotated-81 #f (quote map)) (syntmp-build-annotated-81 #f (quote map))) syntmp-ls-1072))) (syntmp-build-annotated-81 #f (cons (syntmp-build-annotated-81 #f (car syntmp-x-1070)) (map syntmp-regen-1069 (cdr syntmp-x-1070)))))))))))) (syntmp-gen-vector-1068 (lambda (syntmp-x-1073) (cond ((eq? (car syntmp-x-1073) (quote list)) (cons (quote vector) (cdr syntmp-x-1073))) ((eq? (car syntmp-x-1073) (quote quote)) (list (quote quote) (list->vector (cadr syntmp-x-1073)))) (else (list (quote list->vector) syntmp-x-1073))))) (syntmp-gen-append-1067 (lambda (syntmp-x-1074 syntmp-y-1075) (if (equal? syntmp-y-1075 (quote (quote ()))) syntmp-x-1074 (list (quote append) syntmp-x-1074 syntmp-y-1075)))) (syntmp-gen-cons-1066 (lambda (syntmp-x-1076 syntmp-y-1077) (let ((syntmp-t-1078 (car syntmp-y-1077))) (if (memv syntmp-t-1078 (quote (quote))) (if (eq? (car syntmp-x-1076) (quote quote)) (list (quote quote) (cons (cadr syntmp-x-1076) (cadr syntmp-y-1077))) (if (eq? (cadr syntmp-y-1077) (quote ())) (list (quote list) syntmp-x-1076) (list (quote cons) syntmp-x-1076 syntmp-y-1077))) (if (memv syntmp-t-1078 (quote (list))) (cons (quote list) (cons syntmp-x-1076 (cdr syntmp-y-1077))) (list (quote cons) syntmp-x-1076 syntmp-y-1077)))))) (syntmp-gen-map-1065 (lambda (syntmp-e-1079 syntmp-map-env-1080) (let ((syntmp-formals-1081 (map cdr syntmp-map-env-1080)) (syntmp-actuals-1082 (map (lambda (syntmp-x-1083) (list (quote ref) (car syntmp-x-1083))) syntmp-map-env-1080))) (cond ((eq? (car syntmp-e-1079) (quote ref)) (car syntmp-actuals-1082)) ((andmap (lambda (syntmp-x-1084) (and (eq? (car syntmp-x-1084) (quote ref)) (memq (cadr syntmp-x-1084) syntmp-formals-1081))) (cdr syntmp-e-1079)) (cons (quote map) (cons (list (quote primitive) (car syntmp-e-1079)) (map (let ((syntmp-r-1085 (map cons syntmp-formals-1081 syntmp-actuals-1082))) (lambda (syntmp-x-1086) (cdr (assq (cadr syntmp-x-1086) syntmp-r-1085)))) (cdr syntmp-e-1079))))) (else (cons (quote map) (cons (list (quote lambda) syntmp-formals-1081 syntmp-e-1079) syntmp-actuals-1082))))))) (syntmp-gen-mappend-1064 (lambda (syntmp-e-1087 syntmp-map-env-1088) (list (quote apply) (quote (primitive append)) (syntmp-gen-map-1065 syntmp-e-1087 syntmp-map-env-1088)))) (syntmp-gen-ref-1063 (lambda (syntmp-src-1089 syntmp-var-1090 syntmp-level-1091 syntmp-maps-1092) (if (syntmp-fx=-74 syntmp-level-1091 0) (values syntmp-var-1090 syntmp-maps-1092) (if (null? syntmp-maps-1092) (syntax-error syntmp-src-1089 "missing ellipsis in syntax form") (call-with-values (lambda () (syntmp-gen-ref-1063 syntmp-src-1089 syntmp-var-1090 (syntmp-fx--73 syntmp-level-1091 1) (cdr syntmp-maps-1092))) (lambda (syntmp-outer-var-1093 syntmp-outer-maps-1094) (let ((syntmp-b-1095 (assq syntmp-outer-var-1093 (car syntmp-maps-1092)))) (if syntmp-b-1095 (values (cdr syntmp-b-1095) syntmp-maps-1092) (let ((syntmp-inner-var-1096 (syntmp-gen-var-150 (quote tmp)))) (values syntmp-inner-var-1096 (cons (cons (cons syntmp-outer-var-1093 syntmp-inner-var-1096) (car syntmp-maps-1092)) syntmp-outer-maps-1094))))))))))) (syntmp-gen-syntax-1062 (lambda (syntmp-src-1097 syntmp-e-1098 syntmp-r-1099 syntmp-maps-1100 syntmp-ellipsis?-1101) (if (syntmp-id?-102 syntmp-e-1098) (let ((syntmp-label-1102 (syntmp-id-var-name-124 syntmp-e-1098 (quote (()))))) (let ((syntmp-b-1103 (syntmp-lookup-99 syntmp-label-1102 syntmp-r-1099))) (if (eq? (syntmp-binding-type-94 syntmp-b-1103) (quote syntax)) (call-with-values (lambda () (let ((syntmp-var.lev-1104 (syntmp-binding-value-95 syntmp-b-1103))) (syntmp-gen-ref-1063 syntmp-src-1097 (car syntmp-var.lev-1104) (cdr syntmp-var.lev-1104) syntmp-maps-1100))) (lambda (syntmp-var-1105 syntmp-maps-1106) (values (list (quote ref) syntmp-var-1105) syntmp-maps-1106))) (if (syntmp-ellipsis?-1101 syntmp-e-1098) (syntax-error syntmp-src-1097 "misplaced ellipsis in syntax form") (values (list (quote quote) syntmp-e-1098) syntmp-maps-1100))))) ((lambda (syntmp-tmp-1107) ((lambda (syntmp-tmp-1108) (if (if syntmp-tmp-1108 (apply (lambda (syntmp-dots-1109 syntmp-e-1110) (syntmp-ellipsis?-1101 syntmp-dots-1109)) syntmp-tmp-1108) #f) (apply (lambda (syntmp-dots-1111 syntmp-e-1112) (syntmp-gen-syntax-1062 syntmp-src-1097 syntmp-e-1112 syntmp-r-1099 syntmp-maps-1100 (lambda (syntmp-x-1113) #f))) syntmp-tmp-1108) ((lambda (syntmp-tmp-1114) (if (if syntmp-tmp-1114 (apply (lambda (syntmp-x-1115 syntmp-dots-1116 syntmp-y-1117) (syntmp-ellipsis?-1101 syntmp-dots-1116)) syntmp-tmp-1114) #f) (apply (lambda (syntmp-x-1118 syntmp-dots-1119 syntmp-y-1120) (let syntmp-f-1121 ((syntmp-y-1122 syntmp-y-1120) (syntmp-k-1123 (lambda (syntmp-maps-1124) (call-with-values (lambda () (syntmp-gen-syntax-1062 syntmp-src-1097 syntmp-x-1118 syntmp-r-1099 (cons (quote ()) syntmp-maps-1124) syntmp-ellipsis?-1101)) (lambda (syntmp-x-1125 syntmp-maps-1126) (if (null? (car syntmp-maps-1126)) (syntax-error syntmp-src-1097 "extra ellipsis in syntax form") (values (syntmp-gen-map-1065 syntmp-x-1125 (car syntmp-maps-1126)) (cdr syntmp-maps-1126)))))))) ((lambda (syntmp-tmp-1127) ((lambda (syntmp-tmp-1128) (if (if syntmp-tmp-1128 (apply (lambda (syntmp-dots-1129 syntmp-y-1130) (syntmp-ellipsis?-1101 syntmp-dots-1129)) syntmp-tmp-1128) #f) (apply (lambda (syntmp-dots-1131 syntmp-y-1132) (syntmp-f-1121 syntmp-y-1132 (lambda (syntmp-maps-1133) (call-with-values (lambda () (syntmp-k-1123 (cons (quote ()) syntmp-maps-1133))) (lambda (syntmp-x-1134 syntmp-maps-1135) (if (null? (car syntmp-maps-1135)) (syntax-error syntmp-src-1097 "extra ellipsis in syntax form") (values (syntmp-gen-mappend-1064 syntmp-x-1134 (car syntmp-maps-1135)) (cdr syntmp-maps-1135)))))))) syntmp-tmp-1128) ((lambda (syntmp-_-1136) (call-with-values (lambda () (syntmp-gen-syntax-1062 syntmp-src-1097 syntmp-y-1122 syntmp-r-1099 syntmp-maps-1100 syntmp-ellipsis?-1101)) (lambda (syntmp-y-1137 syntmp-maps-1138) (call-with-values (lambda () (syntmp-k-1123 syntmp-maps-1138)) (lambda (syntmp-x-1139 syntmp-maps-1140) (values (syntmp-gen-append-1067 syntmp-x-1139 syntmp-y-1137) syntmp-maps-1140)))))) syntmp-tmp-1127))) (syntax-dispatch syntmp-tmp-1127 (quote (any . any))))) syntmp-y-1122))) syntmp-tmp-1114) ((lambda (syntmp-tmp-1141) (if syntmp-tmp-1141 (apply (lambda (syntmp-x-1142 syntmp-y-1143) (call-with-values (lambda () (syntmp-gen-syntax-1062 syntmp-src-1097 syntmp-x-1142 syntmp-r-1099 syntmp-maps-1100 syntmp-ellipsis?-1101)) (lambda (syntmp-x-1144 syntmp-maps-1145) (call-with-values (lambda () (syntmp-gen-syntax-1062 syntmp-src-1097 syntmp-y-1143 syntmp-r-1099 syntmp-maps-1145 syntmp-ellipsis?-1101)) (lambda (syntmp-y-1146 syntmp-maps-1147) (values (syntmp-gen-cons-1066 syntmp-x-1144 syntmp-y-1146) syntmp-maps-1147)))))) syntmp-tmp-1141) ((lambda (syntmp-tmp-1148) (if syntmp-tmp-1148 (apply (lambda (syntmp-e1-1149 syntmp-e2-1150) (call-with-values (lambda () (syntmp-gen-syntax-1062 syntmp-src-1097 (cons syntmp-e1-1149 syntmp-e2-1150) syntmp-r-1099 syntmp-maps-1100 syntmp-ellipsis?-1101)) (lambda (syntmp-e-1152 syntmp-maps-1153) (values (syntmp-gen-vector-1068 syntmp-e-1152) syntmp-maps-1153)))) syntmp-tmp-1148) ((lambda (syntmp-_-1154) (values (list (quote quote) syntmp-e-1098) syntmp-maps-1100)) syntmp-tmp-1107))) (syntax-dispatch syntmp-tmp-1107 (quote #(vector (any . each-any))))))) (syntax-dispatch syntmp-tmp-1107 (quote (any . any)))))) (syntax-dispatch syntmp-tmp-1107 (quote (any any . any)))))) (syntax-dispatch syntmp-tmp-1107 (quote (any any))))) syntmp-e-1098))))) (lambda (syntmp-e-1155 syntmp-r-1156 syntmp-w-1157 syntmp-s-1158) (let ((syntmp-e-1159 (syntmp-source-wrap-131 syntmp-e-1155 syntmp-w-1157 syntmp-s-1158))) ((lambda (syntmp-tmp-1160) ((lambda (syntmp-tmp-1161) (if syntmp-tmp-1161 (apply (lambda (syntmp-_-1162 syntmp-x-1163) (call-with-values (lambda () (syntmp-gen-syntax-1062 syntmp-e-1159 syntmp-x-1163 syntmp-r-1156 (quote ()) syntmp-ellipsis?-147)) (lambda (syntmp-e-1164 syntmp-maps-1165) (syntmp-regen-1069 syntmp-e-1164)))) syntmp-tmp-1161) ((lambda (syntmp-_-1166) (syntax-error syntmp-e-1159)) syntmp-tmp-1160))) (syntax-dispatch syntmp-tmp-1160 (quote (any any))))) syntmp-e-1159))))) (syntmp-global-extend-100 (quote core) (quote lambda) (lambda (syntmp-e-1167 syntmp-r-1168 syntmp-w-1169 syntmp-s-1170) ((lambda (syntmp-tmp-1171) ((lambda (syntmp-tmp-1172) (if syntmp-tmp-1172 (apply (lambda (syntmp-_-1173 syntmp-c-1174) (syntmp-chi-lambda-clause-143 (syntmp-source-wrap-131 syntmp-e-1167 syntmp-w-1169 syntmp-s-1170) syntmp-c-1174 syntmp-r-1168 syntmp-w-1169 (lambda (syntmp-vars-1175 syntmp-body-1176) (syntmp-build-annotated-81 syntmp-s-1170 (list (quote lambda) syntmp-vars-1175 syntmp-body-1176))))) syntmp-tmp-1172) (syntax-error syntmp-tmp-1171))) (syntax-dispatch syntmp-tmp-1171 (quote (any . any))))) syntmp-e-1167))) (syntmp-global-extend-100 (quote core) (quote let) (letrec ((syntmp-chi-let-1177 (lambda (syntmp-e-1178 syntmp-r-1179 syntmp-w-1180 syntmp-s-1181 syntmp-constructor-1182 syntmp-ids-1183 syntmp-vals-1184 syntmp-exps-1185) (if (not (syntmp-valid-bound-ids?-127 syntmp-ids-1183)) (syntax-error syntmp-e-1178 "duplicate bound variable in") (let ((syntmp-labels-1186 (syntmp-gen-labels-108 syntmp-ids-1183)) (syntmp-new-vars-1187 (map syntmp-gen-var-150 syntmp-ids-1183))) (let ((syntmp-nw-1188 (syntmp-make-binding-wrap-119 syntmp-ids-1183 syntmp-labels-1186 syntmp-w-1180)) (syntmp-nr-1189 (syntmp-extend-var-env-97 syntmp-labels-1186 syntmp-new-vars-1187 syntmp-r-1179))) (syntmp-constructor-1182 syntmp-s-1181 syntmp-new-vars-1187 (map (lambda (syntmp-x-1190) (syntmp-chi-138 syntmp-x-1190 syntmp-r-1179 syntmp-w-1180)) syntmp-vals-1184) (syntmp-chi-body-142 syntmp-exps-1185 (syntmp-source-wrap-131 syntmp-e-1178 syntmp-nw-1188 syntmp-s-1181) syntmp-nr-1189 syntmp-nw-1188)))))))) (lambda (syntmp-e-1191 syntmp-r-1192 syntmp-w-1193 syntmp-s-1194) ((lambda (syntmp-tmp-1195) ((lambda (syntmp-tmp-1196) (if syntmp-tmp-1196 (apply (lambda (syntmp-_-1197 syntmp-id-1198 syntmp-val-1199 syntmp-e1-1200 syntmp-e2-1201) (syntmp-chi-let-1177 syntmp-e-1191 syntmp-r-1192 syntmp-w-1193 syntmp-s-1194 syntmp-build-let-84 syntmp-id-1198 syntmp-val-1199 (cons syntmp-e1-1200 syntmp-e2-1201))) syntmp-tmp-1196) ((lambda (syntmp-tmp-1205) (if (if syntmp-tmp-1205 (apply (lambda (syntmp-_-1206 syntmp-f-1207 syntmp-id-1208 syntmp-val-1209 syntmp-e1-1210 syntmp-e2-1211) (syntmp-id?-102 syntmp-f-1207)) syntmp-tmp-1205) #f) (apply (lambda (syntmp-_-1212 syntmp-f-1213 syntmp-id-1214 syntmp-val-1215 syntmp-e1-1216 syntmp-e2-1217) (syntmp-chi-let-1177 syntmp-e-1191 syntmp-r-1192 syntmp-w-1193 syntmp-s-1194 syntmp-build-named-let-85 (cons syntmp-f-1213 syntmp-id-1214) syntmp-val-1215 (cons syntmp-e1-1216 syntmp-e2-1217))) syntmp-tmp-1205) ((lambda (syntmp-_-1221) (syntax-error (syntmp-source-wrap-131 syntmp-e-1191 syntmp-w-1193 syntmp-s-1194))) syntmp-tmp-1195))) (syntax-dispatch syntmp-tmp-1195 (quote (any any #(each (any any)) any . each-any)))))) (syntax-dispatch syntmp-tmp-1195 (quote (any #(each (any any)) any . each-any))))) syntmp-e-1191)))) (syntmp-global-extend-100 (quote core) (quote letrec) (lambda (syntmp-e-1222 syntmp-r-1223 syntmp-w-1224 syntmp-s-1225) ((lambda (syntmp-tmp-1226) ((lambda (syntmp-tmp-1227) (if syntmp-tmp-1227 (apply (lambda (syntmp-_-1228 syntmp-id-1229 syntmp-val-1230 syntmp-e1-1231 syntmp-e2-1232) (let ((syntmp-ids-1233 syntmp-id-1229)) (if (not (syntmp-valid-bound-ids?-127 syntmp-ids-1233)) (syntax-error syntmp-e-1222 "duplicate bound variable in") (let ((syntmp-labels-1235 (syntmp-gen-labels-108 syntmp-ids-1233)) (syntmp-new-vars-1236 (map syntmp-gen-var-150 syntmp-ids-1233))) (let ((syntmp-w-1237 (syntmp-make-binding-wrap-119 syntmp-ids-1233 syntmp-labels-1235 syntmp-w-1224)) (syntmp-r-1238 (syntmp-extend-var-env-97 syntmp-labels-1235 syntmp-new-vars-1236 syntmp-r-1223))) (syntmp-build-letrec-86 syntmp-s-1225 syntmp-new-vars-1236 (map (lambda (syntmp-x-1239) (syntmp-chi-138 syntmp-x-1239 syntmp-r-1238 syntmp-w-1237)) syntmp-val-1230) (syntmp-chi-body-142 (cons syntmp-e1-1231 syntmp-e2-1232) (syntmp-source-wrap-131 syntmp-e-1222 syntmp-w-1237 syntmp-s-1225) syntmp-r-1238 syntmp-w-1237))))))) syntmp-tmp-1227) ((lambda (syntmp-_-1242) (syntax-error (syntmp-source-wrap-131 syntmp-e-1222 syntmp-w-1224 syntmp-s-1225))) syntmp-tmp-1226))) (syntax-dispatch syntmp-tmp-1226 (quote (any #(each (any any)) any . each-any))))) syntmp-e-1222))) (syntmp-global-extend-100 (quote core) (quote set!) (lambda (syntmp-e-1243 syntmp-r-1244 syntmp-w-1245 syntmp-s-1246) ((lambda (syntmp-tmp-1247) ((lambda (syntmp-tmp-1248) (if (if syntmp-tmp-1248 (apply (lambda (syntmp-_-1249 syntmp-id-1250 syntmp-val-1251) (syntmp-id?-102 syntmp-id-1250)) syntmp-tmp-1248) #f) (apply (lambda (syntmp-_-1252 syntmp-id-1253 syntmp-val-1254) (let ((syntmp-val-1255 (syntmp-chi-138 syntmp-val-1254 syntmp-r-1244 syntmp-w-1245)) (syntmp-n-1256 (syntmp-id-var-name-124 syntmp-id-1253 syntmp-w-1245))) (let ((syntmp-b-1257 (syntmp-lookup-99 syntmp-n-1256 syntmp-r-1244))) (let ((syntmp-t-1258 (syntmp-binding-type-94 syntmp-b-1257))) (if (memv syntmp-t-1258 (quote (lexical))) (syntmp-build-annotated-81 syntmp-s-1246 (list (quote set!) (syntmp-binding-value-95 syntmp-b-1257) syntmp-val-1255)) (if (memv syntmp-t-1258 (quote (global))) (syntmp-build-annotated-81 syntmp-s-1246 (list (quote set!) syntmp-n-1256 syntmp-val-1255)) (if (memv syntmp-t-1258 (quote (displaced-lexical))) (syntax-error (syntmp-wrap-130 syntmp-id-1253 syntmp-w-1245) "identifier out of context") (syntax-error (syntmp-source-wrap-131 syntmp-e-1243 syntmp-w-1245 syntmp-s-1246))))))))) syntmp-tmp-1248) ((lambda (syntmp-tmp-1259) (if syntmp-tmp-1259 (apply (lambda (syntmp-_-1260 syntmp-getter-1261 syntmp-arg-1262 syntmp-val-1263) (syntmp-build-annotated-81 syntmp-s-1246 (cons (syntmp-chi-138 (list (quote #(syntax-object setter ((top) #(ribcage #(_ getter arg val) #((top) (top) (top) (top)) #("i" "i" "i" "i")) #(ribcage () () ()) #(ribcage #(e r w s) #((top) (top) (top) (top)) #("i" "i" "i" "i")) #(ribcage (lambda-var-list gen-var strip strip-annotation ellipsis? chi-void eval-local-transformer chi-local-syntax chi-lambda-clause chi-body chi-macro chi-application chi-expr chi chi-top syntax-type chi-when-list chi-install-global chi-top-sequence chi-sequence source-wrap wrap bound-id-member? distinct-bound-ids? valid-bound-ids? bound-id=? free-id=? id-var-name same-marks? join-marks join-wraps smart-append make-binding-wrap extend-ribcage! make-empty-ribcage new-mark anti-mark the-anti-mark top-marked? top-wrap empty-wrap set-ribcage-labels! set-ribcage-marks! set-ribcage-symnames! ribcage-labels ribcage-marks ribcage-symnames ribcage? make-ribcage gen-labels gen-label make-rename rename-marks rename-new rename-old subst-rename? wrap-subst wrap-marks make-wrap id-sym-name&marks id-sym-name id? nonsymbol-id? global-extend lookup macros-only-env extend-var-env extend-env null-env binding-value binding-type make-binding arg-check source-annotation no-source unannotate set-syntax-object-wrap! set-syntax-object-expression! syntax-object-wrap syntax-object-expression syntax-object? make-syntax-object build-lexical-var build-letrec build-named-let build-let build-sequence build-data build-primref build-lambda build-global-definition build-global-assignment build-global-reference build-lexical-assignment build-lexical-reference build-conditional build-application build-annotated get-global-definition-hook put-global-definition-hook gensym-hook error-hook local-eval-hook top-level-eval-hook fx< fx= fx- fx+ noexpand) ((top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top)) ("i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i")) #(ribcage (define-structure) ((top)) ("i"))))) syntmp-getter-1261) syntmp-r-1244 syntmp-w-1245) (map (lambda (syntmp-e-1264) (syntmp-chi-138 syntmp-e-1264 syntmp-r-1244 syntmp-w-1245)) (append syntmp-arg-1262 (list syntmp-val-1263)))))) syntmp-tmp-1259) ((lambda (syntmp-_-1266) (syntax-error (syntmp-source-wrap-131 syntmp-e-1243 syntmp-w-1245 syntmp-s-1246))) syntmp-tmp-1247))) (syntax-dispatch syntmp-tmp-1247 (quote (any (any . each-any) any)))))) (syntax-dispatch syntmp-tmp-1247 (quote (any any any))))) syntmp-e-1243))) (syntmp-global-extend-100 (quote begin) (quote begin) (quote ())) (syntmp-global-extend-100 (quote define) (quote define) (quote ())) (syntmp-global-extend-100 (quote define-syntax) (quote define-syntax) (quote ())) (syntmp-global-extend-100 (quote eval-when) (quote eval-when) (quote ())) (syntmp-global-extend-100 (quote core) (quote syntax-case) (letrec ((syntmp-gen-syntax-case-1270 (lambda (syntmp-x-1271 syntmp-keys-1272 syntmp-clauses-1273 syntmp-r-1274) (if (null? syntmp-clauses-1273) (syntmp-build-annotated-81 #f (list (syntmp-build-annotated-81 #f (quote syntax-error)) syntmp-x-1271)) ((lambda (syntmp-tmp-1275) ((lambda (syntmp-tmp-1276) (if syntmp-tmp-1276 (apply (lambda (syntmp-pat-1277 syntmp-exp-1278) (if (and (syntmp-id?-102 syntmp-pat-1277) (andmap (lambda (syntmp-x-1279) (not (syntmp-free-id=?-125 syntmp-pat-1277 syntmp-x-1279))) (cons (quote #(syntax-object ... ((top) #(ribcage #(pat exp) #((top) (top)) #("i" "i")) #(ribcage () () ()) #(ribcage #(x keys clauses r) #((top) (top) (top) (top)) #("i" "i" "i" "i")) #(ribcage (gen-syntax-case gen-clause build-dispatch-call convert-pattern) ((top) (top) (top) (top)) ("i" "i" "i" "i")) #(ribcage (lambda-var-list gen-var strip strip-annotation ellipsis? chi-void eval-local-transformer chi-local-syntax chi-lambda-clause chi-body chi-macro chi-application chi-expr chi chi-top syntax-type chi-when-list chi-install-global chi-top-sequence chi-sequence source-wrap wrap bound-id-member? distinct-bound-ids? valid-bound-ids? bound-id=? free-id=? id-var-name same-marks? join-marks join-wraps smart-append make-binding-wrap extend-ribcage! make-empty-ribcage new-mark anti-mark the-anti-mark top-marked? top-wrap empty-wrap set-ribcage-labels! set-ribcage-marks! set-ribcage-symnames! ribcage-labels ribcage-marks ribcage-symnames ribcage? make-ribcage gen-labels gen-label make-rename rename-marks rename-new rename-old subst-rename? wrap-subst wrap-marks make-wrap id-sym-name&marks id-sym-name id? nonsymbol-id? global-extend lookup macros-only-env extend-var-env extend-env null-env binding-value binding-type make-binding arg-check source-annotation no-source unannotate set-syntax-object-wrap! set-syntax-object-expression! syntax-object-wrap syntax-object-expression syntax-object? make-syntax-object build-lexical-var build-letrec build-named-let build-let build-sequence build-data build-primref build-lambda build-global-definition build-global-assignment build-global-reference build-lexical-assignment build-lexical-reference build-conditional build-application build-annotated get-global-definition-hook put-global-definition-hook gensym-hook error-hook local-eval-hook top-level-eval-hook fx< fx= fx- fx+ noexpand) ((top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top) (top)) ("i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i" "i")) #(ribcage (define-structure) ((top)) ("i"))))) syntmp-keys-1272))) (let ((syntmp-labels-1280 (list (syntmp-gen-label-107))) (syntmp-var-1281 (syntmp-gen-var-150 syntmp-pat-1277))) (syntmp-build-annotated-81 #f (list (syntmp-build-annotated-81 #f (list (quote lambda) (list syntmp-var-1281) (syntmp-chi-138 syntmp-exp-1278 (syntmp-extend-env-96 syntmp-labels-1280 (list (cons (quote syntax) (cons syntmp-var-1281 0))) syntmp-r-1274) (syntmp-make-binding-wrap-119 (list syntmp-pat-1277) syntmp-labels-1280 (quote (())))))) syntmp-x-1271))) (syntmp-gen-clause-1269 syntmp-x-1271 syntmp-keys-1272 (cdr syntmp-clauses-1273) syntmp-r-1274 syntmp-pat-1277 #t syntmp-exp-1278))) syntmp-tmp-1276) ((lambda (syntmp-tmp-1282) (if syntmp-tmp-1282 (apply (lambda (syntmp-pat-1283 syntmp-fender-1284 syntmp-exp-1285) (syntmp-gen-clause-1269 syntmp-x-1271 syntmp-keys-1272 (cdr syntmp-clauses-1273) syntmp-r-1274 syntmp-pat-1283 syntmp-fender-1284 syntmp-exp-1285)) syntmp-tmp-1282) ((lambda (syntmp-_-1286) (syntax-error (car syntmp-clauses-1273) "invalid syntax-case clause")) syntmp-tmp-1275))) (syntax-dispatch syntmp-tmp-1275 (quote (any any any)))))) (syntax-dispatch syntmp-tmp-1275 (quote (any any))))) (car syntmp-clauses-1273))))) (syntmp-gen-clause-1269 (lambda (syntmp-x-1287 syntmp-keys-1288 syntmp-clauses-1289 syntmp-r-1290 syntmp-pat-1291 syntmp-fender-1292 syntmp-exp-1293) (call-with-values (lambda () (syntmp-convert-pattern-1267 syntmp-pat-1291 syntmp-keys-1288)) (lambda (syntmp-p-1294 syntmp-pvars-1295) (cond ((not (syntmp-distinct-bound-ids?-128 (map car syntmp-pvars-1295))) (syntax-error syntmp-pat-1291 "duplicate pattern variable in syntax-case pattern")) ((not (andmap (lambda (syntmp-x-1296) (not (syntmp-ellipsis?-147 (car syntmp-x-1296)))) syntmp-pvars-1295)) (syntax-error syntmp-pat-1291 "misplaced ellipsis in syntax-case pattern")) (else (let ((syntmp-y-1297 (syntmp-gen-var-150 (quote tmp)))) (syntmp-build-annotated-81 #f (list (syntmp-build-annotated-81 #f (list (quote lambda) (list syntmp-y-1297) (let ((syntmp-y-1298 (syntmp-build-annotated-81 #f syntmp-y-1297))) (syntmp-build-annotated-81 #f (list (quote if) ((lambda (syntmp-tmp-1299) ((lambda (syntmp-tmp-1300) (if syntmp-tmp-1300 (apply (lambda () syntmp-y-1298) syntmp-tmp-1300) ((lambda (syntmp-_-1301) (syntmp-build-annotated-81 #f (list (quote if) syntmp-y-1298 (syntmp-build-dispatch-call-1268 syntmp-pvars-1295 syntmp-fender-1292 syntmp-y-1298 syntmp-r-1290) (syntmp-build-data-82 #f #f)))) syntmp-tmp-1299))) (syntax-dispatch syntmp-tmp-1299 (quote #(atom #t))))) syntmp-fender-1292) (syntmp-build-dispatch-call-1268 syntmp-pvars-1295 syntmp-exp-1293 syntmp-y-1298 syntmp-r-1290) (syntmp-gen-syntax-case-1270 syntmp-x-1287 syntmp-keys-1288 syntmp-clauses-1289 syntmp-r-1290)))))) (if (eq? syntmp-p-1294 (quote any)) (syntmp-build-annotated-81 #f (list (syntmp-build-annotated-81 #f (quote list)) syntmp-x-1287)) (syntmp-build-annotated-81 #f (list (syntmp-build-annotated-81 #f (quote syntax-dispatch)) syntmp-x-1287 (syntmp-build-data-82 #f syntmp-p-1294))))))))))))) (syntmp-build-dispatch-call-1268 (lambda (syntmp-pvars-1302 syntmp-exp-1303 syntmp-y-1304 syntmp-r-1305) (let ((syntmp-ids-1306 (map car syntmp-pvars-1302)) (syntmp-levels-1307 (map cdr syntmp-pvars-1302))) (let ((syntmp-labels-1308 (syntmp-gen-labels-108 syntmp-ids-1306)) (syntmp-new-vars-1309 (map syntmp-gen-var-150 syntmp-ids-1306))) (syntmp-build-annotated-81 #f (list (syntmp-build-annotated-81 #f (quote apply)) (syntmp-build-annotated-81 #f (list (quote lambda) syntmp-new-vars-1309 (syntmp-chi-138 syntmp-exp-1303 (syntmp-extend-env-96 syntmp-labels-1308 (map (lambda (syntmp-var-1310 syntmp-level-1311) (cons (quote syntax) (cons syntmp-var-1310 syntmp-level-1311))) syntmp-new-vars-1309 (map cdr syntmp-pvars-1302)) syntmp-r-1305) (syntmp-make-binding-wrap-119 syntmp-ids-1306 syntmp-labels-1308 (quote (())))))) syntmp-y-1304)))))) (syntmp-convert-pattern-1267 (lambda (syntmp-pattern-1312 syntmp-keys-1313) (let syntmp-cvt-1314 ((syntmp-p-1315 syntmp-pattern-1312) (syntmp-n-1316 0) (syntmp-ids-1317 (quote ()))) (if (syntmp-id?-102 syntmp-p-1315) (if (syntmp-bound-id-member?-129 syntmp-p-1315 syntmp-keys-1313) (values (vector (quote free-id) syntmp-p-1315) syntmp-ids-1317) (values (quote any) (cons (cons syntmp-p-1315 syntmp-n-1316) syntmp-ids-1317))) ((lambda (syntmp-tmp-1318) ((lambda (syntmp-tmp-1319) (if (if syntmp-tmp-1319 (apply (lambda (syntmp-x-1320 syntmp-dots-1321) (syntmp-ellipsis?-147 syntmp-dots-1321)) syntmp-tmp-1319) #f) (apply (lambda (syntmp-x-1322 syntmp-dots-1323) (call-with-values (lambda () (syntmp-cvt-1314 syntmp-x-1322 (syntmp-fx+-72 syntmp-n-1316 1) syntmp-ids-1317)) (lambda (syntmp-p-1324 syntmp-ids-1325) (values (if (eq? syntmp-p-1324 (quote any)) (quote each-any) (vector (quote each) syntmp-p-1324)) syntmp-ids-1325)))) syntmp-tmp-1319) ((lambda (syntmp-tmp-1326) (if syntmp-tmp-1326 (apply (lambda (syntmp-x-1327 syntmp-y-1328) (call-with-values (lambda () (syntmp-cvt-1314 syntmp-y-1328 syntmp-n-1316 syntmp-ids-1317)) (lambda (syntmp-y-1329 syntmp-ids-1330) (call-with-values (lambda () (syntmp-cvt-1314 syntmp-x-1327 syntmp-n-1316 syntmp-ids-1330)) (lambda (syntmp-x-1331 syntmp-ids-1332) (values (cons syntmp-x-1331 syntmp-y-1329) syntmp-ids-1332)))))) syntmp-tmp-1326) ((lambda (syntmp-tmp-1333) (if syntmp-tmp-1333 (apply (lambda () (values (quote ()) syntmp-ids-1317)) syntmp-tmp-1333) ((lambda (syntmp-tmp-1334) (if syntmp-tmp-1334 (apply (lambda (syntmp-x-1335) (call-with-values (lambda () (syntmp-cvt-1314 syntmp-x-1335 syntmp-n-1316 syntmp-ids-1317)) (lambda (syntmp-p-1337 syntmp-ids-1338) (values (vector (quote vector) syntmp-p-1337) syntmp-ids-1338)))) syntmp-tmp-1334) ((lambda (syntmp-x-1339) (values (vector (quote atom) (syntmp-strip-149 syntmp-p-1315 (quote (())))) syntmp-ids-1317)) syntmp-tmp-1318))) (syntax-dispatch syntmp-tmp-1318 (quote #(vector each-any)))))) (syntax-dispatch syntmp-tmp-1318 (quote ()))))) (syntax-dispatch syntmp-tmp-1318 (quote (any . any)))))) (syntax-dispatch syntmp-tmp-1318 (quote (any any))))) syntmp-p-1315)))))) (lambda (syntmp-e-1340 syntmp-r-1341 syntmp-w-1342 syntmp-s-1343) (let ((syntmp-e-1344 (syntmp-source-wrap-131 syntmp-e-1340 syntmp-w-1342 syntmp-s-1343))) ((lambda (syntmp-tmp-1345) ((lambda (syntmp-tmp-1346) (if syntmp-tmp-1346 (apply (lambda (syntmp-_-1347 syntmp-val-1348 syntmp-key-1349 syntmp-m-1350) (if (andmap (lambda (syntmp-x-1351) (and (syntmp-id?-102 syntmp-x-1351) (not (syntmp-ellipsis?-147 syntmp-x-1351)))) syntmp-key-1349) (let ((syntmp-x-1353 (syntmp-gen-var-150 (quote tmp)))) (syntmp-build-annotated-81 syntmp-s-1343 (list (syntmp-build-annotated-81 #f (list (quote lambda) (list syntmp-x-1353) (syntmp-gen-syntax-case-1270 (syntmp-build-annotated-81 #f syntmp-x-1353) syntmp-key-1349 syntmp-m-1350 syntmp-r-1341))) (syntmp-chi-138 syntmp-val-1348 syntmp-r-1341 (quote (())))))) (syntax-error syntmp-e-1344 "invalid literals list in"))) syntmp-tmp-1346) (syntax-error syntmp-tmp-1345))) (syntax-dispatch syntmp-tmp-1345 (quote (any any each-any . each-any))))) syntmp-e-1344))))) (set! sc-expand (let ((syntmp-m-1356 (quote e)) (syntmp-esew-1357 (quote (eval)))) (lambda (syntmp-x-1358) (if (and (pair? syntmp-x-1358) (equal? (car syntmp-x-1358) syntmp-noexpand-71)) (cadr syntmp-x-1358) (syntmp-chi-top-137 syntmp-x-1358 (quote ()) (quote ((top))) syntmp-m-1356 syntmp-esew-1357))))) (set! sc-expand3 (let ((syntmp-m-1359 (quote e)) (syntmp-esew-1360 (quote (eval)))) (lambda (syntmp-x-1362 . syntmp-rest-1361) (if (and (pair? syntmp-x-1362) (equal? (car syntmp-x-1362) syntmp-noexpand-71)) (cadr syntmp-x-1362) (syntmp-chi-top-137 syntmp-x-1362 (quote ()) (quote ((top))) (if (null? syntmp-rest-1361) syntmp-m-1359 (car syntmp-rest-1361)) (if (or (null? syntmp-rest-1361) (null? (cdr syntmp-rest-1361))) syntmp-esew-1360 (cadr syntmp-rest-1361))))))) (set! identifier? (lambda (syntmp-x-1363) (syntmp-nonsymbol-id?-101 syntmp-x-1363))) (set! datum->syntax-object (lambda (syntmp-id-1364 syntmp-datum-1365) (syntmp-make-syntax-object-87 syntmp-datum-1365 (syntmp-syntax-object-wrap-90 syntmp-id-1364)))) (set! syntax-object->datum (lambda (syntmp-x-1366) (syntmp-strip-149 syntmp-x-1366 (quote (()))))) (set! generate-temporaries (lambda (syntmp-ls-1367) (begin (let ((syntmp-x-1368 syntmp-ls-1367)) (if (not (list? syntmp-x-1368)) (syntmp-error-hook-78 (quote generate-temporaries) "invalid argument" syntmp-x-1368))) (map (lambda (syntmp-x-1369) (syntmp-wrap-130 (gensym) (quote ((top))))) syntmp-ls-1367)))) (set! free-identifier=? (lambda (syntmp-x-1370 syntmp-y-1371) (begin (let ((syntmp-x-1372 syntmp-x-1370)) (if (not (syntmp-nonsymbol-id?-101 syntmp-x-1372)) (syntmp-error-hook-78 (quote free-identifier=?) "invalid argument" syntmp-x-1372))) (let ((syntmp-x-1373 syntmp-y-1371)) (if (not (syntmp-nonsymbol-id?-101 syntmp-x-1373)) (syntmp-error-hook-78 (quote free-identifier=?) "invalid argument" syntmp-x-1373))) (syntmp-free-id=?-125 syntmp-x-1370 syntmp-y-1371)))) (set! bound-identifier=? (lambda (syntmp-x-1374 syntmp-y-1375) (begin (let ((syntmp-x-1376 syntmp-x-1374)) (if (not (syntmp-nonsymbol-id?-101 syntmp-x-1376)) (syntmp-error-hook-78 (quote bound-identifier=?) "invalid argument" syntmp-x-1376))) (let ((syntmp-x-1377 syntmp-y-1375)) (if (not (syntmp-nonsymbol-id?-101 syntmp-x-1377)) (syntmp-error-hook-78 (quote bound-identifier=?) "invalid argument" syntmp-x-1377))) (syntmp-bound-id=?-126 syntmp-x-1374 syntmp-y-1375)))) (set! syntax-error (lambda (syntmp-object-1379 . syntmp-messages-1378) (begin (for-each (lambda (syntmp-x-1380) (let ((syntmp-x-1381 syntmp-x-1380)) (if (not (string? syntmp-x-1381)) (syntmp-error-hook-78 (quote syntax-error) "invalid argument" syntmp-x-1381)))) syntmp-messages-1378) (let ((syntmp-message-1382 (if (null? syntmp-messages-1378) "invalid syntax" (apply string-append syntmp-messages-1378)))) (syntmp-error-hook-78 #f syntmp-message-1382 (syntmp-strip-149 syntmp-object-1379 (quote (())))))))) (set! install-global-transformer (lambda (syntmp-sym-1383 syntmp-v-1384) (begin (let ((syntmp-x-1385 syntmp-sym-1383)) (if (not (symbol? syntmp-x-1385)) (syntmp-error-hook-78 (quote define-syntax) "invalid argument" syntmp-x-1385))) (let ((syntmp-x-1386 syntmp-v-1384)) (if (not (procedure? syntmp-x-1386)) (syntmp-error-hook-78 (quote define-syntax) "invalid argument" syntmp-x-1386))) (syntmp-global-extend-100 (quote macro) syntmp-sym-1383 syntmp-v-1384)))) (letrec ((syntmp-match-1391 (lambda (syntmp-e-1392 syntmp-p-1393 syntmp-w-1394 syntmp-r-1395) (cond ((not syntmp-r-1395) #f) ((eq? syntmp-p-1393 (quote any)) (cons (syntmp-wrap-130 syntmp-e-1392 syntmp-w-1394) syntmp-r-1395)) ((syntmp-syntax-object?-88 syntmp-e-1392) (syntmp-match*-1390 (let ((syntmp-e-1396 (syntmp-syntax-object-expression-89 syntmp-e-1392))) (if (annotation? syntmp-e-1396) (annotation-expression syntmp-e-1396) syntmp-e-1396)) syntmp-p-1393 (syntmp-join-wraps-121 syntmp-w-1394 (syntmp-syntax-object-wrap-90 syntmp-e-1392)) syntmp-r-1395)) (else (syntmp-match*-1390 (let ((syntmp-e-1397 syntmp-e-1392)) (if (annotation? syntmp-e-1397) (annotation-expression syntmp-e-1397) syntmp-e-1397)) syntmp-p-1393 syntmp-w-1394 syntmp-r-1395))))) (syntmp-match*-1390 (lambda (syntmp-e-1398 syntmp-p-1399 syntmp-w-1400 syntmp-r-1401) (cond ((null? syntmp-p-1399) (and (null? syntmp-e-1398) syntmp-r-1401)) ((pair? syntmp-p-1399) (and (pair? syntmp-e-1398) (syntmp-match-1391 (car syntmp-e-1398) (car syntmp-p-1399) syntmp-w-1400 (syntmp-match-1391 (cdr syntmp-e-1398) (cdr syntmp-p-1399) syntmp-w-1400 syntmp-r-1401)))) ((eq? syntmp-p-1399 (quote each-any)) (let ((syntmp-l-1402 (syntmp-match-each-any-1388 syntmp-e-1398 syntmp-w-1400))) (and syntmp-l-1402 (cons syntmp-l-1402 syntmp-r-1401)))) (else (let ((syntmp-t-1403 (vector-ref syntmp-p-1399 0))) (if (memv syntmp-t-1403 (quote (each))) (if (null? syntmp-e-1398) (syntmp-match-empty-1389 (vector-ref syntmp-p-1399 1) syntmp-r-1401) (let ((syntmp-l-1404 (syntmp-match-each-1387 syntmp-e-1398 (vector-ref syntmp-p-1399 1) syntmp-w-1400))) (and syntmp-l-1404 (let syntmp-collect-1405 ((syntmp-l-1406 syntmp-l-1404)) (if (null? (car syntmp-l-1406)) syntmp-r-1401 (cons (map car syntmp-l-1406) (syntmp-collect-1405 (map cdr syntmp-l-1406)))))))) (if (memv syntmp-t-1403 (quote (free-id))) (and (syntmp-id?-102 syntmp-e-1398) (syntmp-free-id=?-125 (syntmp-wrap-130 syntmp-e-1398 syntmp-w-1400) (vector-ref syntmp-p-1399 1)) syntmp-r-1401) (if (memv syntmp-t-1403 (quote (atom))) (and (equal? (vector-ref syntmp-p-1399 1) (syntmp-strip-149 syntmp-e-1398 syntmp-w-1400)) syntmp-r-1401) (if (memv syntmp-t-1403 (quote (vector))) (and (vector? syntmp-e-1398) (syntmp-match-1391 (vector->list syntmp-e-1398) (vector-ref syntmp-p-1399 1) syntmp-w-1400 syntmp-r-1401))))))))))) (syntmp-match-empty-1389 (lambda (syntmp-p-1407 syntmp-r-1408) (cond ((null? syntmp-p-1407) syntmp-r-1408) ((eq? syntmp-p-1407 (quote any)) (cons (quote ()) syntmp-r-1408)) ((pair? syntmp-p-1407) (syntmp-match-empty-1389 (car syntmp-p-1407) (syntmp-match-empty-1389 (cdr syntmp-p-1407) syntmp-r-1408))) ((eq? syntmp-p-1407 (quote each-any)) (cons (quote ()) syntmp-r-1408)) (else (let ((syntmp-t-1409 (vector-ref syntmp-p-1407 0))) (if (memv syntmp-t-1409 (quote (each))) (syntmp-match-empty-1389 (vector-ref syntmp-p-1407 1) syntmp-r-1408) (if (memv syntmp-t-1409 (quote (free-id atom))) syntmp-r-1408 (if (memv syntmp-t-1409 (quote (vector))) (syntmp-match-empty-1389 (vector-ref syntmp-p-1407 1) syntmp-r-1408))))))))) (syntmp-match-each-any-1388 (lambda (syntmp-e-1410 syntmp-w-1411) (cond ((annotation? syntmp-e-1410) (syntmp-match-each-any-1388 (annotation-expression syntmp-e-1410) syntmp-w-1411)) ((pair? syntmp-e-1410) (let ((syntmp-l-1412 (syntmp-match-each-any-1388 (cdr syntmp-e-1410) syntmp-w-1411))) (and syntmp-l-1412 (cons (syntmp-wrap-130 (car syntmp-e-1410) syntmp-w-1411) syntmp-l-1412)))) ((null? syntmp-e-1410) (quote ())) ((syntmp-syntax-object?-88 syntmp-e-1410) (syntmp-match-each-any-1388 (syntmp-syntax-object-expression-89 syntmp-e-1410) (syntmp-join-wraps-121 syntmp-w-1411 (syntmp-syntax-object-wrap-90 syntmp-e-1410)))) (else #f)))) (syntmp-match-each-1387 (lambda (syntmp-e-1413 syntmp-p-1414 syntmp-w-1415) (cond ((annotation? syntmp-e-1413) (syntmp-match-each-1387 (annotation-expression syntmp-e-1413) syntmp-p-1414 syntmp-w-1415)) ((pair? syntmp-e-1413) (let ((syntmp-first-1416 (syntmp-match-1391 (car syntmp-e-1413) syntmp-p-1414 syntmp-w-1415 (quote ())))) (and syntmp-first-1416 (let ((syntmp-rest-1417 (syntmp-match-each-1387 (cdr syntmp-e-1413) syntmp-p-1414 syntmp-w-1415))) (and syntmp-rest-1417 (cons syntmp-first-1416 syntmp-rest-1417)))))) ((null? syntmp-e-1413) (quote ())) ((syntmp-syntax-object?-88 syntmp-e-1413) (syntmp-match-each-1387 (syntmp-syntax-object-expression-89 syntmp-e-1413) syntmp-p-1414 (syntmp-join-wraps-121 syntmp-w-1415 (syntmp-syntax-object-wrap-90 syntmp-e-1413)))) (else #f))))) (begin (set! syntax-dispatch (lambda (syntmp-e-1418 syntmp-p-1419) (cond ((eq? syntmp-p-1419 (quote any)) (list syntmp-e-1418)) ((syntmp-syntax-object?-88 syntmp-e-1418) (syntmp-match*-1390 (let ((syntmp-e-1420 (syntmp-syntax-object-expression-89 syntmp-e-1418))) (if (annotation? syntmp-e-1420) (annotation-expression syntmp-e-1420) syntmp-e-1420)) syntmp-p-1419 (syntmp-syntax-object-wrap-90 syntmp-e-1418) (quote ()))) (else (syntmp-match*-1390 (let ((syntmp-e-1421 syntmp-e-1418)) (if (annotation? syntmp-e-1421) (annotation-expression syntmp-e-1421) syntmp-e-1421)) syntmp-p-1419 (quote (())) (quote ())))))) (set! sc-chi syntmp-chi-138))))) -(install-global-transformer (quote with-syntax) (lambda (syntmp-x-1422) ((lambda (syntmp-tmp-1423) ((lambda (syntmp-tmp-1424) (if syntmp-tmp-1424 (apply (lambda (syntmp-_-1425 syntmp-e1-1426 syntmp-e2-1427) (cons (quote #(syntax-object begin ((top) #(ribcage #(_ e1 e2) #((top) (top) (top)) #("i" "i" "i")) #(ribcage () () ()) #(ribcage #(x) #((top)) #("i"))))) (cons syntmp-e1-1426 syntmp-e2-1427))) syntmp-tmp-1424) ((lambda (syntmp-tmp-1429) (if syntmp-tmp-1429 (apply (lambda (syntmp-_-1430 syntmp-out-1431 syntmp-in-1432 syntmp-e1-1433 syntmp-e2-1434) (list (quote #(syntax-object syntax-case ((top) #(ribcage #(_ out in e1 e2) #((top) (top) (top) (top) (top)) #("i" "i" "i" "i" "i")) #(ribcage () () ()) #(ribcage #(x) #((top)) #("i"))))) syntmp-in-1432 (quote ()) (list syntmp-out-1431 (cons (quote #(syntax-object begin ((top) #(ribcage #(_ out in e1 e2) #((top) (top) (top) (top) (top)) #("i" "i" "i" "i" "i")) #(ribcage () () ()) #(ribcage #(x) #((top)) #("i"))))) (cons syntmp-e1-1433 syntmp-e2-1434))))) syntmp-tmp-1429) ((lambda (syntmp-tmp-1436) (if syntmp-tmp-1436 (apply (lambda (syntmp-_-1437 syntmp-out-1438 syntmp-in-1439 syntmp-e1-1440 syntmp-e2-1441) (list (quote #(syntax-object syntax-case ((top) #(ribcage #(_ out in e1 e2) #((top) (top) (top) (top) (top)) #("i" "i" "i" "i" "i")) #(ribcage () () ()) #(ribcage #(x) #((top)) #("i"))))) (cons (quote #(syntax-object list ((top) #(ribcage #(_ out in e1 e2) #((top) (top) (top) (top) (top)) #("i" "i" "i" "i" "i")) #(ribcage () () ()) #(ribcage #(x) #((top)) #("i"))))) syntmp-in-1439) (quote ()) (list syntmp-out-1438 (cons (quote #(syntax-object begin ((top) #(ribcage #(_ out in e1 e2) #((top) (top) (top) (top) (top)) #("i" "i" "i" "i" "i")) #(ribcage () () ()) #(ribcage #(x) #((top)) #("i"))))) (cons syntmp-e1-1440 syntmp-e2-1441))))) syntmp-tmp-1436) (syntax-error syntmp-tmp-1423))) (syntax-dispatch syntmp-tmp-1423 (quote (any #(each (any any)) any . each-any)))))) (syntax-dispatch syntmp-tmp-1423 (quote (any ((any any)) any . each-any)))))) (syntax-dispatch syntmp-tmp-1423 (quote (any () any . each-any))))) syntmp-x-1422))) -(install-global-transformer (quote syntax-rules) (lambda (syntmp-x-1463) ((lambda (syntmp-tmp-1464) ((lambda (syntmp-tmp-1465) (if syntmp-tmp-1465 (apply (lambda (syntmp-_-1466 syntmp-k-1467 syntmp-keyword-1468 syntmp-pattern-1469 syntmp-template-1470) (list (quote #(syntax-object lambda ((top) #(ribcage #(_ k keyword pattern template) #((top) (top) (top) (top) (top)) #("i" "i" "i" "i" "i")) #(ribcage () () ()) #(ribcage #(x) #((top)) #("i"))))) (quote (#(syntax-object x ((top) #(ribcage #(_ k keyword pattern template) #((top) (top) (top) (top) (top)) #("i" "i" "i" "i" "i")) #(ribcage () () ()) #(ribcage #(x) #((top)) #("i")))))) (cons (quote #(syntax-object syntax-case ((top) #(ribcage #(_ k keyword pattern template) #((top) (top) (top) (top) (top)) #("i" "i" "i" "i" "i")) #(ribcage () () ()) #(ribcage #(x) #((top)) #("i"))))) (cons (quote #(syntax-object x ((top) #(ribcage #(_ k keyword pattern template) #((top) (top) (top) (top) (top)) #("i" "i" "i" "i" "i")) #(ribcage () () ()) #(ribcage #(x) #((top)) #("i"))))) (cons syntmp-k-1467 (map (lambda (syntmp-tmp-1473 syntmp-tmp-1472) (list (cons (quote #(syntax-object dummy ((top) #(ribcage #(_ k keyword pattern template) #((top) (top) (top) (top) (top)) #("i" "i" "i" "i" "i")) #(ribcage () () ()) #(ribcage #(x) #((top)) #("i"))))) syntmp-tmp-1472) (list (quote #(syntax-object syntax ((top) #(ribcage #(_ k keyword pattern template) #((top) (top) (top) (top) (top)) #("i" "i" "i" "i" "i")) #(ribcage () () ()) #(ribcage #(x) #((top)) #("i"))))) syntmp-tmp-1473))) syntmp-template-1470 syntmp-pattern-1469)))))) syntmp-tmp-1465) (syntax-error syntmp-tmp-1464))) (syntax-dispatch syntmp-tmp-1464 (quote (any each-any . #(each ((any . any) any))))))) syntmp-x-1463))) -(install-global-transformer (quote let*) (lambda (syntmp-x-1484) ((lambda (syntmp-tmp-1485) ((lambda (syntmp-tmp-1486) (if (if syntmp-tmp-1486 (apply (lambda (syntmp-let*-1487 syntmp-x-1488 syntmp-v-1489 syntmp-e1-1490 syntmp-e2-1491) (andmap identifier? syntmp-x-1488)) syntmp-tmp-1486) #f) (apply (lambda (syntmp-let*-1493 syntmp-x-1494 syntmp-v-1495 syntmp-e1-1496 syntmp-e2-1497) (let syntmp-f-1498 ((syntmp-bindings-1499 (map list syntmp-x-1494 syntmp-v-1495))) (if (null? syntmp-bindings-1499) (cons (quote #(syntax-object let ((top) #(ribcage () () ()) #(ribcage #(f bindings) #((top) (top)) #("i" "i")) #(ribcage #(let* x v e1 e2) #((top) (top) (top) (top) (top)) #("i" "i" "i" "i" "i")) #(ribcage () () ()) #(ribcage #(x) #((top)) #("i"))))) (cons (quote ()) (cons syntmp-e1-1496 syntmp-e2-1497))) ((lambda (syntmp-tmp-1503) ((lambda (syntmp-tmp-1504) (if syntmp-tmp-1504 (apply (lambda (syntmp-body-1505 syntmp-binding-1506) (list (quote #(syntax-object let ((top) #(ribcage #(body binding) #((top) (top)) #("i" "i")) #(ribcage () () ()) #(ribcage #(f bindings) #((top) (top)) #("i" "i")) #(ribcage #(let* x v e1 e2) #((top) (top) (top) (top) (top)) #("i" "i" "i" "i" "i")) #(ribcage () () ()) #(ribcage #(x) #((top)) #("i"))))) (list syntmp-binding-1506) syntmp-body-1505)) syntmp-tmp-1504) (syntax-error syntmp-tmp-1503))) (syntax-dispatch syntmp-tmp-1503 (quote (any any))))) (list (syntmp-f-1498 (cdr syntmp-bindings-1499)) (car syntmp-bindings-1499)))))) syntmp-tmp-1486) (syntax-error syntmp-tmp-1485))) (syntax-dispatch syntmp-tmp-1485 (quote (any #(each (any any)) any . each-any))))) syntmp-x-1484))) -(install-global-transformer (quote do) (lambda (syntmp-orig-x-1526) ((lambda (syntmp-tmp-1527) ((lambda (syntmp-tmp-1528) (if syntmp-tmp-1528 (apply (lambda (syntmp-_-1529 syntmp-var-1530 syntmp-init-1531 syntmp-step-1532 syntmp-e0-1533 syntmp-e1-1534 syntmp-c-1535) ((lambda (syntmp-tmp-1536) ((lambda (syntmp-tmp-1537) (if syntmp-tmp-1537 (apply (lambda (syntmp-step-1538) ((lambda (syntmp-tmp-1539) ((lambda (syntmp-tmp-1540) (if syntmp-tmp-1540 (apply (lambda () (list (quote #(syntax-object let ((top) #(ribcage #(step) #((top)) #("i")) #(ribcage #(_ var init step e0 e1 c) #((top) (top) (top) (top) (top) (top) (top)) #("i" "i" "i" "i" "i" "i" "i")) #(ribcage () () ()) #(ribcage #(orig-x) #((top)) #("i"))))) (quote #(syntax-object doloop ((top) #(ribcage #(step) #((top)) #("i")) #(ribcage #(_ var init step e0 e1 c) #((top) (top) (top) (top) (top) (top) (top)) #("i" "i" "i" "i" "i" "i" "i")) #(ribcage () () ()) #(ribcage #(orig-x) #((top)) #("i"))))) (map list syntmp-var-1530 syntmp-init-1531) (list (quote #(syntax-object if ((top) #(ribcage #(step) #((top)) #("i")) #(ribcage #(_ var init step e0 e1 c) #((top) (top) (top) (top) (top) (top) (top)) #("i" "i" "i" "i" "i" "i" "i")) #(ribcage () () ()) #(ribcage #(orig-x) #((top)) #("i"))))) (list (quote #(syntax-object not ((top) #(ribcage #(step) #((top)) #("i")) #(ribcage #(_ var init step e0 e1 c) #((top) (top) (top) (top) (top) (top) (top)) #("i" "i" "i" "i" "i" "i" "i")) #(ribcage () () ()) #(ribcage #(orig-x) #((top)) #("i"))))) syntmp-e0-1533) (cons (quote #(syntax-object begin ((top) #(ribcage #(step) #((top)) #("i")) #(ribcage #(_ var init step e0 e1 c) #((top) (top) (top) (top) (top) (top) (top)) #("i" "i" "i" "i" "i" "i" "i")) #(ribcage () () ()) #(ribcage #(orig-x) #((top)) #("i"))))) (append syntmp-c-1535 (list (cons (quote #(syntax-object doloop ((top) #(ribcage #(step) #((top)) #("i")) #(ribcage #(_ var init step e0 e1 c) #((top) (top) (top) (top) (top) (top) (top)) #("i" "i" "i" "i" "i" "i" "i")) #(ribcage () () ()) #(ribcage #(orig-x) #((top)) #("i"))))) syntmp-step-1538))))))) syntmp-tmp-1540) ((lambda (syntmp-tmp-1545) (if syntmp-tmp-1545 (apply (lambda (syntmp-e1-1546 syntmp-e2-1547) (list (quote #(syntax-object let ((top) #(ribcage #(e1 e2) #((top) (top)) #("i" "i")) #(ribcage #(step) #((top)) #("i")) #(ribcage #(_ var init step e0 e1 c) #((top) (top) (top) (top) (top) (top) (top)) #("i" "i" "i" "i" "i" "i" "i")) #(ribcage () () ()) #(ribcage #(orig-x) #((top)) #("i"))))) (quote #(syntax-object doloop ((top) #(ribcage #(e1 e2) #((top) (top)) #("i" "i")) #(ribcage #(step) #((top)) #("i")) #(ribcage #(_ var init step e0 e1 c) #((top) (top) (top) (top) (top) (top) (top)) #("i" "i" "i" "i" "i" "i" "i")) #(ribcage () () ()) #(ribcage #(orig-x) #((top)) #("i"))))) (map list syntmp-var-1530 syntmp-init-1531) (list (quote #(syntax-object if ((top) #(ribcage #(e1 e2) #((top) (top)) #("i" "i")) #(ribcage #(step) #((top)) #("i")) #(ribcage #(_ var init step e0 e1 c) #((top) (top) (top) (top) (top) (top) (top)) #("i" "i" "i" "i" "i" "i" "i")) #(ribcage () () ()) #(ribcage #(orig-x) #((top)) #("i"))))) syntmp-e0-1533 (cons (quote #(syntax-object begin ((top) #(ribcage #(e1 e2) #((top) (top)) #("i" "i")) #(ribcage #(step) #((top)) #("i")) #(ribcage #(_ var init step e0 e1 c) #((top) (top) (top) (top) (top) (top) (top)) #("i" "i" "i" "i" "i" "i" "i")) #(ribcage () () ()) #(ribcage #(orig-x) #((top)) #("i"))))) (cons syntmp-e1-1546 syntmp-e2-1547)) (cons (quote #(syntax-object begin ((top) #(ribcage #(e1 e2) #((top) (top)) #("i" "i")) #(ribcage #(step) #((top)) #("i")) #(ribcage #(_ var init step e0 e1 c) #((top) (top) (top) (top) (top) (top) (top)) #("i" "i" "i" "i" "i" "i" "i")) #(ribcage () () ()) #(ribcage #(orig-x) #((top)) #("i"))))) (append syntmp-c-1535 (list (cons (quote #(syntax-object doloop ((top) #(ribcage #(e1 e2) #((top) (top)) #("i" "i")) #(ribcage #(step) #((top)) #("i")) #(ribcage #(_ var init step e0 e1 c) #((top) (top) (top) (top) (top) (top) (top)) #("i" "i" "i" "i" "i" "i" "i")) #(ribcage () () ()) #(ribcage #(orig-x) #((top)) #("i"))))) syntmp-step-1538))))))) syntmp-tmp-1545) (syntax-error syntmp-tmp-1539))) (syntax-dispatch syntmp-tmp-1539 (quote (any . each-any)))))) (syntax-dispatch syntmp-tmp-1539 (quote ())))) syntmp-e1-1534)) syntmp-tmp-1537) (syntax-error syntmp-tmp-1536))) (syntax-dispatch syntmp-tmp-1536 (quote each-any)))) (map (lambda (syntmp-v-1554 syntmp-s-1555) ((lambda (syntmp-tmp-1556) ((lambda (syntmp-tmp-1557) (if syntmp-tmp-1557 (apply (lambda () syntmp-v-1554) syntmp-tmp-1557) ((lambda (syntmp-tmp-1558) (if syntmp-tmp-1558 (apply (lambda (syntmp-e-1559) syntmp-e-1559) syntmp-tmp-1558) ((lambda (syntmp-_-1560) (syntax-error syntmp-orig-x-1526)) syntmp-tmp-1556))) (syntax-dispatch syntmp-tmp-1556 (quote (any)))))) (syntax-dispatch syntmp-tmp-1556 (quote ())))) syntmp-s-1555)) syntmp-var-1530 syntmp-step-1532))) syntmp-tmp-1528) (syntax-error syntmp-tmp-1527))) (syntax-dispatch syntmp-tmp-1527 (quote (any #(each (any any . any)) (any . each-any) . each-any))))) syntmp-orig-x-1526))) -(install-global-transformer (quote quasiquote) (letrec ((syntmp-quasicons-1588 (lambda (syntmp-x-1592 syntmp-y-1593) ((lambda (syntmp-tmp-1594) ((lambda (syntmp-tmp-1595) (if syntmp-tmp-1595 (apply (lambda (syntmp-x-1596 syntmp-y-1597) ((lambda (syntmp-tmp-1598) ((lambda (syntmp-tmp-1599) (if syntmp-tmp-1599 (apply (lambda (syntmp-dy-1600) ((lambda (syntmp-tmp-1601) ((lambda (syntmp-tmp-1602) (if syntmp-tmp-1602 (apply (lambda (syntmp-dx-1603) (list (quote #(syntax-object quote ((top) #(ribcage #(dx) #((top)) #("i")) #(ribcage #(dy) #((top)) #("i")) #(ribcage #(x y) #((top) (top)) #("i" "i")) #(ribcage () () ()) #(ribcage () () ()) #(ribcage #(x y) #((top) (top)) #("i" "i")) #(ribcage #(quasicons quasiappend quasivector quasi) #((top) (top) (top) (top)) #("i" "i" "i" "i"))))) (cons syntmp-dx-1603 syntmp-dy-1600))) syntmp-tmp-1602) ((lambda (syntmp-_-1604) (if (null? syntmp-dy-1600) (list (quote #(syntax-object list ((top) #(ribcage #(_) #((top)) #("i")) #(ribcage #(dy) #((top)) #("i")) #(ribcage #(x y) #((top) (top)) #("i" "i")) #(ribcage () () ()) #(ribcage () () ()) #(ribcage #(x y) #((top) (top)) #("i" "i")) #(ribcage #(quasicons quasiappend quasivector quasi) #((top) (top) (top) (top)) #("i" "i" "i" "i"))))) syntmp-x-1596) (list (quote #(syntax-object cons ((top) #(ribcage #(_) #((top)) #("i")) #(ribcage #(dy) #((top)) #("i")) #(ribcage #(x y) #((top) (top)) #("i" "i")) #(ribcage () () ()) #(ribcage () () ()) #(ribcage #(x y) #((top) (top)) #("i" "i")) #(ribcage #(quasicons quasiappend quasivector quasi) #((top) (top) (top) (top)) #("i" "i" "i" "i"))))) syntmp-x-1596 syntmp-y-1597))) syntmp-tmp-1601))) (syntax-dispatch syntmp-tmp-1601 (quote (#(free-id #(syntax-object quote ((top) #(ribcage #(dy) #((top)) #("i")) #(ribcage #(x y) #((top) (top)) #("i" "i")) #(ribcage () () ()) #(ribcage () () ()) #(ribcage #(x y) #((top) (top)) #("i" "i")) #(ribcage #(quasicons quasiappend quasivector quasi) #((top) (top) (top) (top)) #("i" "i" "i" "i"))))) any))))) syntmp-x-1596)) syntmp-tmp-1599) ((lambda (syntmp-tmp-1605) (if syntmp-tmp-1605 (apply (lambda (syntmp-stuff-1606) (cons (quote #(syntax-object list ((top) #(ribcage #(stuff) #((top)) #("i")) #(ribcage #(x y) #((top) (top)) #("i" "i")) #(ribcage () () ()) #(ribcage () () ()) #(ribcage #(x y) #((top) (top)) #("i" "i")) #(ribcage #(quasicons quasiappend quasivector quasi) #((top) (top) (top) (top)) #("i" "i" "i" "i"))))) (cons syntmp-x-1596 syntmp-stuff-1606))) syntmp-tmp-1605) ((lambda (syntmp-else-1607) (list (quote #(syntax-object cons ((top) #(ribcage #(else) #((top)) #("i")) #(ribcage #(x y) #((top) (top)) #("i" "i")) #(ribcage () () ()) #(ribcage () () ()) #(ribcage #(x y) #((top) (top)) #("i" "i")) #(ribcage #(quasicons quasiappend quasivector quasi) #((top) (top) (top) (top)) #("i" "i" "i" "i"))))) syntmp-x-1596 syntmp-y-1597)) syntmp-tmp-1598))) (syntax-dispatch syntmp-tmp-1598 (quote (#(free-id #(syntax-object list ((top) #(ribcage #(x y) #((top) (top)) #("i" "i")) #(ribcage () () ()) #(ribcage () () ()) #(ribcage #(x y) #((top) (top)) #("i" "i")) #(ribcage #(quasicons quasiappend quasivector quasi) #((top) (top) (top) (top)) #("i" "i" "i" "i"))))) . any)))))) (syntax-dispatch syntmp-tmp-1598 (quote (#(free-id #(syntax-object quote ((top) #(ribcage #(x y) #((top) (top)) #("i" "i")) #(ribcage () () ()) #(ribcage () () ()) #(ribcage #(x y) #((top) (top)) #("i" "i")) #(ribcage #(quasicons quasiappend quasivector quasi) #((top) (top) (top) (top)) #("i" "i" "i" "i"))))) any))))) syntmp-y-1597)) syntmp-tmp-1595) (syntax-error syntmp-tmp-1594))) (syntax-dispatch syntmp-tmp-1594 (quote (any any))))) (list syntmp-x-1592 syntmp-y-1593)))) (syntmp-quasiappend-1589 (lambda (syntmp-x-1608 syntmp-y-1609) ((lambda (syntmp-tmp-1610) ((lambda (syntmp-tmp-1611) (if syntmp-tmp-1611 (apply (lambda (syntmp-x-1612 syntmp-y-1613) ((lambda (syntmp-tmp-1614) ((lambda (syntmp-tmp-1615) (if syntmp-tmp-1615 (apply (lambda () syntmp-x-1612) syntmp-tmp-1615) ((lambda (syntmp-_-1616) (list (quote #(syntax-object append ((top) #(ribcage #(_) #((top)) #("i")) #(ribcage #(x y) #((top) (top)) #("i" "i")) #(ribcage () () ()) #(ribcage () () ()) #(ribcage #(x y) #((top) (top)) #("i" "i")) #(ribcage #(quasicons quasiappend quasivector quasi) #((top) (top) (top) (top)) #("i" "i" "i" "i"))))) syntmp-x-1612 syntmp-y-1613)) syntmp-tmp-1614))) (syntax-dispatch syntmp-tmp-1614 (quote (#(free-id #(syntax-object quote ((top) #(ribcage #(x y) #((top) (top)) #("i" "i")) #(ribcage () () ()) #(ribcage () () ()) #(ribcage #(x y) #((top) (top)) #("i" "i")) #(ribcage #(quasicons quasiappend quasivector quasi) #((top) (top) (top) (top)) #("i" "i" "i" "i"))))) ()))))) syntmp-y-1613)) syntmp-tmp-1611) (syntax-error syntmp-tmp-1610))) (syntax-dispatch syntmp-tmp-1610 (quote (any any))))) (list syntmp-x-1608 syntmp-y-1609)))) (syntmp-quasivector-1590 (lambda (syntmp-x-1617) ((lambda (syntmp-tmp-1618) ((lambda (syntmp-x-1619) ((lambda (syntmp-tmp-1620) ((lambda (syntmp-tmp-1621) (if syntmp-tmp-1621 (apply (lambda (syntmp-x-1622) (list (quote #(syntax-object quote ((top) #(ribcage #(x) #((top)) #("i")) #(ribcage #(x) #((top)) #("i")) #(ribcage () () ()) #(ribcage () () ()) #(ribcage #(x) #((top)) #("i")) #(ribcage #(quasicons quasiappend quasivector quasi) #((top) (top) (top) (top)) #("i" "i" "i" "i"))))) (list->vector syntmp-x-1622))) syntmp-tmp-1621) ((lambda (syntmp-tmp-1624) (if syntmp-tmp-1624 (apply (lambda (syntmp-x-1625) (cons (quote #(syntax-object vector ((top) #(ribcage #(x) #((top)) #("i")) #(ribcage #(x) #((top)) #("i")) #(ribcage () () ()) #(ribcage () () ()) #(ribcage #(x) #((top)) #("i")) #(ribcage #(quasicons quasiappend quasivector quasi) #((top) (top) (top) (top)) #("i" "i" "i" "i"))))) syntmp-x-1625)) syntmp-tmp-1624) ((lambda (syntmp-_-1627) (list (quote #(syntax-object list->vector ((top) #(ribcage #(_) #((top)) #("i")) #(ribcage #(x) #((top)) #("i")) #(ribcage () () ()) #(ribcage () () ()) #(ribcage #(x) #((top)) #("i")) #(ribcage #(quasicons quasiappend quasivector quasi) #((top) (top) (top) (top)) #("i" "i" "i" "i"))))) syntmp-x-1619)) syntmp-tmp-1620))) (syntax-dispatch syntmp-tmp-1620 (quote (#(free-id #(syntax-object list ((top) #(ribcage #(x) #((top)) #("i")) #(ribcage () () ()) #(ribcage () () ()) #(ribcage #(x) #((top)) #("i")) #(ribcage #(quasicons quasiappend quasivector quasi) #((top) (top) (top) (top)) #("i" "i" "i" "i"))))) . each-any)))))) (syntax-dispatch syntmp-tmp-1620 (quote (#(free-id #(syntax-object quote ((top) #(ribcage #(x) #((top)) #("i")) #(ribcage () () ()) #(ribcage () () ()) #(ribcage #(x) #((top)) #("i")) #(ribcage #(quasicons quasiappend quasivector quasi) #((top) (top) (top) (top)) #("i" "i" "i" "i"))))) each-any))))) syntmp-x-1619)) syntmp-tmp-1618)) syntmp-x-1617))) (syntmp-quasi-1591 (lambda (syntmp-p-1628 syntmp-lev-1629) ((lambda (syntmp-tmp-1630) ((lambda (syntmp-tmp-1631) (if syntmp-tmp-1631 (apply (lambda (syntmp-p-1632) (if (= syntmp-lev-1629 0) syntmp-p-1632 (syntmp-quasicons-1588 (quote (#(syntax-object quote ((top) #(ribcage #(p) #((top)) #("i")) #(ribcage () () ()) #(ribcage #(p lev) #((top) (top)) #("i" "i")) #(ribcage #(quasicons quasiappend quasivector quasi) #((top) (top) (top) (top)) #("i" "i" "i" "i")))) #(syntax-object unquote ((top) #(ribcage #(p) #((top)) #("i")) #(ribcage () () ()) #(ribcage #(p lev) #((top) (top)) #("i" "i")) #(ribcage #(quasicons quasiappend quasivector quasi) #((top) (top) (top) (top)) #("i" "i" "i" "i")))))) (syntmp-quasi-1591 (list syntmp-p-1632) (- syntmp-lev-1629 1))))) syntmp-tmp-1631) ((lambda (syntmp-tmp-1633) (if syntmp-tmp-1633 (apply (lambda (syntmp-p-1634 syntmp-q-1635) (if (= syntmp-lev-1629 0) (syntmp-quasiappend-1589 syntmp-p-1634 (syntmp-quasi-1591 syntmp-q-1635 syntmp-lev-1629)) (syntmp-quasicons-1588 (syntmp-quasicons-1588 (quote (#(syntax-object quote ((top) #(ribcage #(p q) #((top) (top)) #("i" "i")) #(ribcage () () ()) #(ribcage #(p lev) #((top) (top)) #("i" "i")) #(ribcage #(quasicons quasiappend quasivector quasi) #((top) (top) (top) (top)) #("i" "i" "i" "i")))) #(syntax-object unquote-splicing ((top) #(ribcage #(p q) #((top) (top)) #("i" "i")) #(ribcage () () ()) #(ribcage #(p lev) #((top) (top)) #("i" "i")) #(ribcage #(quasicons quasiappend quasivector quasi) #((top) (top) (top) (top)) #("i" "i" "i" "i")))))) (syntmp-quasi-1591 (list syntmp-p-1634) (- syntmp-lev-1629 1))) (syntmp-quasi-1591 syntmp-q-1635 syntmp-lev-1629)))) syntmp-tmp-1633) ((lambda (syntmp-tmp-1636) (if syntmp-tmp-1636 (apply (lambda (syntmp-p-1637) (syntmp-quasicons-1588 (quote (#(syntax-object quote ((top) #(ribcage #(p) #((top)) #("i")) #(ribcage () () ()) #(ribcage #(p lev) #((top) (top)) #("i" "i")) #(ribcage #(quasicons quasiappend quasivector quasi) #((top) (top) (top) (top)) #("i" "i" "i" "i")))) #(syntax-object quasiquote ((top) #(ribcage #(p) #((top)) #("i")) #(ribcage () () ()) #(ribcage #(p lev) #((top) (top)) #("i" "i")) #(ribcage #(quasicons quasiappend quasivector quasi) #((top) (top) (top) (top)) #("i" "i" "i" "i")))))) (syntmp-quasi-1591 (list syntmp-p-1637) (+ syntmp-lev-1629 1)))) syntmp-tmp-1636) ((lambda (syntmp-tmp-1638) (if syntmp-tmp-1638 (apply (lambda (syntmp-p-1639 syntmp-q-1640) (syntmp-quasicons-1588 (syntmp-quasi-1591 syntmp-p-1639 syntmp-lev-1629) (syntmp-quasi-1591 syntmp-q-1640 syntmp-lev-1629))) syntmp-tmp-1638) ((lambda (syntmp-tmp-1641) (if syntmp-tmp-1641 (apply (lambda (syntmp-x-1642) (syntmp-quasivector-1590 (syntmp-quasi-1591 syntmp-x-1642 syntmp-lev-1629))) syntmp-tmp-1641) ((lambda (syntmp-p-1644) (list (quote #(syntax-object quote ((top) #(ribcage #(p) #((top)) #("i")) #(ribcage () () ()) #(ribcage #(p lev) #((top) (top)) #("i" "i")) #(ribcage #(quasicons quasiappend quasivector quasi) #((top) (top) (top) (top)) #("i" "i" "i" "i"))))) syntmp-p-1644)) syntmp-tmp-1630))) (syntax-dispatch syntmp-tmp-1630 (quote #(vector each-any)))))) (syntax-dispatch syntmp-tmp-1630 (quote (any . any)))))) (syntax-dispatch syntmp-tmp-1630 (quote (#(free-id #(syntax-object quasiquote ((top) #(ribcage () () ()) #(ribcage #(p lev) #((top) (top)) #("i" "i")) #(ribcage #(quasicons quasiappend quasivector quasi) #((top) (top) (top) (top)) #("i" "i" "i" "i"))))) any)))))) (syntax-dispatch syntmp-tmp-1630 (quote ((#(free-id #(syntax-object unquote-splicing ((top) #(ribcage () () ()) #(ribcage #(p lev) #((top) (top)) #("i" "i")) #(ribcage #(quasicons quasiappend quasivector quasi) #((top) (top) (top) (top)) #("i" "i" "i" "i"))))) any) . any)))))) (syntax-dispatch syntmp-tmp-1630 (quote (#(free-id #(syntax-object unquote ((top) #(ribcage () () ()) #(ribcage #(p lev) #((top) (top)) #("i" "i")) #(ribcage #(quasicons quasiappend quasivector quasi) #((top) (top) (top) (top)) #("i" "i" "i" "i"))))) any))))) syntmp-p-1628)))) (lambda (syntmp-x-1645) ((lambda (syntmp-tmp-1646) ((lambda (syntmp-tmp-1647) (if syntmp-tmp-1647 (apply (lambda (syntmp-_-1648 syntmp-e-1649) (syntmp-quasi-1591 syntmp-e-1649 0)) syntmp-tmp-1647) (syntax-error syntmp-tmp-1646))) (syntax-dispatch syntmp-tmp-1646 (quote (any any))))) syntmp-x-1645)))) -(install-global-transformer (quote include) (lambda (syntmp-x-1709) (letrec ((syntmp-read-file-1710 (lambda (syntmp-fn-1711 syntmp-k-1712) (let ((syntmp-p-1713 (open-input-file syntmp-fn-1711))) (let syntmp-f-1714 ((syntmp-x-1715 (read syntmp-p-1713))) (if (eof-object? syntmp-x-1715) (begin (close-input-port syntmp-p-1713) (quote ())) (cons (datum->syntax-object syntmp-k-1712 syntmp-x-1715) (syntmp-f-1714 (read syntmp-p-1713))))))))) ((lambda (syntmp-tmp-1716) ((lambda (syntmp-tmp-1717) (if syntmp-tmp-1717 (apply (lambda (syntmp-k-1718 syntmp-filename-1719) (let ((syntmp-fn-1720 (syntax-object->datum syntmp-filename-1719))) ((lambda (syntmp-tmp-1721) ((lambda (syntmp-tmp-1722) (if syntmp-tmp-1722 (apply (lambda (syntmp-exp-1723) (cons (quote #(syntax-object begin ((top) #(ribcage #(exp) #((top)) #("i")) #(ribcage () () ()) #(ribcage () () ()) #(ribcage #(fn) #((top)) #("i")) #(ribcage #(k filename) #((top) (top)) #("i" "i")) #(ribcage (read-file) ((top)) ("i")) #(ribcage #(x) #((top)) #("i"))))) syntmp-exp-1723)) syntmp-tmp-1722) (syntax-error syntmp-tmp-1721))) (syntax-dispatch syntmp-tmp-1721 (quote each-any)))) (syntmp-read-file-1710 syntmp-fn-1720 syntmp-k-1718)))) syntmp-tmp-1717) (syntax-error syntmp-tmp-1716))) (syntax-dispatch syntmp-tmp-1716 (quote (any any))))) syntmp-x-1709)))) -(install-global-transformer (quote unquote) (lambda (syntmp-x-1740) ((lambda (syntmp-tmp-1741) ((lambda (syntmp-tmp-1742) (if syntmp-tmp-1742 (apply (lambda (syntmp-_-1743 syntmp-e-1744) (error (quote unquote) "expression ,~s not valid outside of quasiquote" (syntax-object->datum syntmp-e-1744))) syntmp-tmp-1742) (syntax-error syntmp-tmp-1741))) (syntax-dispatch syntmp-tmp-1741 (quote (any any))))) syntmp-x-1740))) -(install-global-transformer (quote unquote-splicing) (lambda (syntmp-x-1750) ((lambda (syntmp-tmp-1751) ((lambda (syntmp-tmp-1752) (if syntmp-tmp-1752 (apply (lambda (syntmp-_-1753 syntmp-e-1754) (error (quote unquote-splicing) "expression ,@~s not valid outside of quasiquote" (syntax-object->datum syntmp-e-1754))) syntmp-tmp-1752) (syntax-error syntmp-tmp-1751))) (syntax-dispatch syntmp-tmp-1751 (quote (any any))))) syntmp-x-1750))) -(install-global-transformer (quote case) (lambda (syntmp-x-1760) ((lambda (syntmp-tmp-1761) ((lambda (syntmp-tmp-1762) (if syntmp-tmp-1762 (apply (lambda (syntmp-_-1763 syntmp-e-1764 syntmp-m1-1765 syntmp-m2-1766) ((lambda (syntmp-tmp-1767) ((lambda (syntmp-body-1768) (list (quote #(syntax-object let ((top) #(ribcage #(body) #((top)) #("i")) #(ribcage #(_ e m1 m2) #((top) (top) (top) (top)) #("i" "i" "i" "i")) #(ribcage () () ()) #(ribcage #(x) #((top)) #("i"))))) (list (list (quote #(syntax-object t ((top) #(ribcage #(body) #((top)) #("i")) #(ribcage #(_ e m1 m2) #((top) (top) (top) (top)) #("i" "i" "i" "i")) #(ribcage () () ()) #(ribcage #(x) #((top)) #("i"))))) syntmp-e-1764)) syntmp-body-1768)) syntmp-tmp-1767)) (let syntmp-f-1769 ((syntmp-clause-1770 syntmp-m1-1765) (syntmp-clauses-1771 syntmp-m2-1766)) (if (null? syntmp-clauses-1771) ((lambda (syntmp-tmp-1773) ((lambda (syntmp-tmp-1774) (if syntmp-tmp-1774 (apply (lambda (syntmp-e1-1775 syntmp-e2-1776) (cons (quote #(syntax-object begin ((top) #(ribcage #(e1 e2) #((top) (top)) #("i" "i")) #(ribcage () () ()) #(ribcage #(f clause clauses) #((top) (top) (top)) #("i" "i" "i")) #(ribcage #(_ e m1 m2) #((top) (top) (top) (top)) #("i" "i" "i" "i")) #(ribcage () () ()) #(ribcage #(x) #((top)) #("i"))))) (cons syntmp-e1-1775 syntmp-e2-1776))) syntmp-tmp-1774) ((lambda (syntmp-tmp-1778) (if syntmp-tmp-1778 (apply (lambda (syntmp-k-1779 syntmp-e1-1780 syntmp-e2-1781) (list (quote #(syntax-object if ((top) #(ribcage #(k e1 e2) #((top) (top) (top)) #("i" "i" "i")) #(ribcage () () ()) #(ribcage #(f clause clauses) #((top) (top) (top)) #("i" "i" "i")) #(ribcage #(_ e m1 m2) #((top) (top) (top) (top)) #("i" "i" "i" "i")) #(ribcage () () ()) #(ribcage #(x) #((top)) #("i"))))) (list (quote #(syntax-object memv ((top) #(ribcage #(k e1 e2) #((top) (top) (top)) #("i" "i" "i")) #(ribcage () () ()) #(ribcage #(f clause clauses) #((top) (top) (top)) #("i" "i" "i")) #(ribcage #(_ e m1 m2) #((top) (top) (top) (top)) #("i" "i" "i" "i")) #(ribcage () () ()) #(ribcage #(x) #((top)) #("i"))))) (quote #(syntax-object t ((top) #(ribcage #(k e1 e2) #((top) (top) (top)) #("i" "i" "i")) #(ribcage () () ()) #(ribcage #(f clause clauses) #((top) (top) (top)) #("i" "i" "i")) #(ribcage #(_ e m1 m2) #((top) (top) (top) (top)) #("i" "i" "i" "i")) #(ribcage () () ()) #(ribcage #(x) #((top)) #("i"))))) (list (quote #(syntax-object quote ((top) #(ribcage #(k e1 e2) #((top) (top) (top)) #("i" "i" "i")) #(ribcage () () ()) #(ribcage #(f clause clauses) #((top) (top) (top)) #("i" "i" "i")) #(ribcage #(_ e m1 m2) #((top) (top) (top) (top)) #("i" "i" "i" "i")) #(ribcage () () ()) #(ribcage #(x) #((top)) #("i"))))) syntmp-k-1779)) (cons (quote #(syntax-object begin ((top) #(ribcage #(k e1 e2) #((top) (top) (top)) #("i" "i" "i")) #(ribcage () () ()) #(ribcage #(f clause clauses) #((top) (top) (top)) #("i" "i" "i")) #(ribcage #(_ e m1 m2) #((top) (top) (top) (top)) #("i" "i" "i" "i")) #(ribcage () () ()) #(ribcage #(x) #((top)) #("i"))))) (cons syntmp-e1-1780 syntmp-e2-1781)))) syntmp-tmp-1778) ((lambda (syntmp-_-1784) (syntax-error syntmp-x-1760)) syntmp-tmp-1773))) (syntax-dispatch syntmp-tmp-1773 (quote (each-any any . each-any)))))) (syntax-dispatch syntmp-tmp-1773 (quote (#(free-id #(syntax-object else ((top) #(ribcage () () ()) #(ribcage #(f clause clauses) #((top) (top) (top)) #("i" "i" "i")) #(ribcage #(_ e m1 m2) #((top) (top) (top) (top)) #("i" "i" "i" "i")) #(ribcage () () ()) #(ribcage #(x) #((top)) #("i"))))) any . each-any))))) syntmp-clause-1770) ((lambda (syntmp-tmp-1785) ((lambda (syntmp-rest-1786) ((lambda (syntmp-tmp-1787) ((lambda (syntmp-tmp-1788) (if syntmp-tmp-1788 (apply (lambda (syntmp-k-1789 syntmp-e1-1790 syntmp-e2-1791) (list (quote #(syntax-object if ((top) #(ribcage #(k e1 e2) #((top) (top) (top)) #("i" "i" "i")) #(ribcage #(rest) #((top)) #("i")) #(ribcage () () ()) #(ribcage #(f clause clauses) #((top) (top) (top)) #("i" "i" "i")) #(ribcage #(_ e m1 m2) #((top) (top) (top) (top)) #("i" "i" "i" "i")) #(ribcage () () ()) #(ribcage #(x) #((top)) #("i"))))) (list (quote #(syntax-object memv ((top) #(ribcage #(k e1 e2) #((top) (top) (top)) #("i" "i" "i")) #(ribcage #(rest) #((top)) #("i")) #(ribcage () () ()) #(ribcage #(f clause clauses) #((top) (top) (top)) #("i" "i" "i")) #(ribcage #(_ e m1 m2) #((top) (top) (top) (top)) #("i" "i" "i" "i")) #(ribcage () () ()) #(ribcage #(x) #((top)) #("i"))))) (quote #(syntax-object t ((top) #(ribcage #(k e1 e2) #((top) (top) (top)) #("i" "i" "i")) #(ribcage #(rest) #((top)) #("i")) #(ribcage () () ()) #(ribcage #(f clause clauses) #((top) (top) (top)) #("i" "i" "i")) #(ribcage #(_ e m1 m2) #((top) (top) (top) (top)) #("i" "i" "i" "i")) #(ribcage () () ()) #(ribcage #(x) #((top)) #("i"))))) (list (quote #(syntax-object quote ((top) #(ribcage #(k e1 e2) #((top) (top) (top)) #("i" "i" "i")) #(ribcage #(rest) #((top)) #("i")) #(ribcage () () ()) #(ribcage #(f clause clauses) #((top) (top) (top)) #("i" "i" "i")) #(ribcage #(_ e m1 m2) #((top) (top) (top) (top)) #("i" "i" "i" "i")) #(ribcage () () ()) #(ribcage #(x) #((top)) #("i"))))) syntmp-k-1789)) (cons (quote #(syntax-object begin ((top) #(ribcage #(k e1 e2) #((top) (top) (top)) #("i" "i" "i")) #(ribcage #(rest) #((top)) #("i")) #(ribcage () () ()) #(ribcage #(f clause clauses) #((top) (top) (top)) #("i" "i" "i")) #(ribcage #(_ e m1 m2) #((top) (top) (top) (top)) #("i" "i" "i" "i")) #(ribcage () () ()) #(ribcage #(x) #((top)) #("i"))))) (cons syntmp-e1-1790 syntmp-e2-1791)) syntmp-rest-1786)) syntmp-tmp-1788) ((lambda (syntmp-_-1794) (syntax-error syntmp-x-1760)) syntmp-tmp-1787))) (syntax-dispatch syntmp-tmp-1787 (quote (each-any any . each-any))))) syntmp-clause-1770)) syntmp-tmp-1785)) (syntmp-f-1769 (car syntmp-clauses-1771) (cdr syntmp-clauses-1771))))))) syntmp-tmp-1762) (syntax-error syntmp-tmp-1761))) (syntax-dispatch syntmp-tmp-1761 (quote (any any any . each-any))))) syntmp-x-1760))) -(install-global-transformer (quote identifier-syntax) (lambda (syntmp-x-1824) ((lambda (syntmp-tmp-1825) ((lambda (syntmp-tmp-1826) (if syntmp-tmp-1826 (apply (lambda (syntmp-_-1827 syntmp-e-1828) (list (quote #(syntax-object lambda ((top) #(ribcage #(_ e) #((top) (top)) #("i" "i")) #(ribcage () () ()) #(ribcage #(x) #((top)) #("i"))))) (quote (#(syntax-object x ((top) #(ribcage #(_ e) #((top) (top)) #("i" "i")) #(ribcage () () ()) #(ribcage #(x) #((top)) #("i")))))) (list (quote #(syntax-object syntax-case ((top) #(ribcage #(_ e) #((top) (top)) #("i" "i")) #(ribcage () () ()) #(ribcage #(x) #((top)) #("i"))))) (quote #(syntax-object x ((top) #(ribcage #(_ e) #((top) (top)) #("i" "i")) #(ribcage () () ()) #(ribcage #(x) #((top)) #("i"))))) (quote ()) (list (quote #(syntax-object id ((top) #(ribcage #(_ e) #((top) (top)) #("i" "i")) #(ribcage () () ()) #(ribcage #(x) #((top)) #("i"))))) (quote (#(syntax-object identifier? ((top) #(ribcage #(_ e) #((top) (top)) #("i" "i")) #(ribcage () () ()) #(ribcage #(x) #((top)) #("i")))) (#(syntax-object syntax ((top) #(ribcage #(_ e) #((top) (top)) #("i" "i")) #(ribcage () () ()) #(ribcage #(x) #((top)) #("i")))) #(syntax-object id ((top) #(ribcage #(_ e) #((top) (top)) #("i" "i")) #(ribcage () () ()) #(ribcage #(x) #((top)) #("i"))))))) (list (quote #(syntax-object syntax ((top) #(ribcage #(_ e) #((top) (top)) #("i" "i")) #(ribcage () () ()) #(ribcage #(x) #((top)) #("i"))))) syntmp-e-1828)) (list (cons syntmp-_-1827 (quote (#(syntax-object x ((top) #(ribcage #(_ e) #((top) (top)) #("i" "i")) #(ribcage () () ()) #(ribcage #(x) #((top)) #("i")))) #(syntax-object ... ((top) #(ribcage #(_ e) #((top) (top)) #("i" "i")) #(ribcage () () ()) #(ribcage #(x) #((top)) #("i"))))))) (list (quote #(syntax-object syntax ((top) #(ribcage #(_ e) #((top) (top)) #("i" "i")) #(ribcage () () ()) #(ribcage #(x) #((top)) #("i"))))) (cons syntmp-e-1828 (quote (#(syntax-object x ((top) #(ribcage #(_ e) #((top) (top)) #("i" "i")) #(ribcage () () ()) #(ribcage #(x) #((top)) #("i")))) #(syntax-object ... ((top) #(ribcage #(_ e) #((top) (top)) #("i" "i")) #(ribcage () () ()) #(ribcage #(x) #((top)) #("i")))))))))))) syntmp-tmp-1826) (syntax-error syntmp-tmp-1825))) (syntax-dispatch syntmp-tmp-1825 (quote (any any))))) syntmp-x-1824))) +(eval-when (compile) (set-current-module (resolve-module (quote (guile))))) +(if #f #f) + +(letrec ((#{and-map*\ 1199}# + (lambda (#{f\ 1239}# #{first\ 1238}# . #{rest\ 1237}#) + (let ((#{t\ 1240}# (null? #{first\ 1238}#))) + (if #{t\ 1240}# + #{t\ 1240}# + (if (null? #{rest\ 1237}#) + (letrec ((#{andmap\ 1241}# + (lambda (#{first\ 1242}#) + (let ((#{x\ 1243}# (car #{first\ 1242}#)) + (#{first\ 1244}# (cdr #{first\ 1242}#))) + (if (null? #{first\ 1244}#) + (#{f\ 1239}# #{x\ 1243}#) + (if (#{f\ 1239}# #{x\ 1243}#) + (#{andmap\ 1241}# #{first\ 1244}#) + #f)))))) + (#{andmap\ 1241}# #{first\ 1238}#)) + (letrec ((#{andmap\ 1245}# + (lambda (#{first\ 1246}# #{rest\ 1247}#) + (let ((#{x\ 1248}# (car #{first\ 1246}#)) + (#{xr\ 1249}# (map car #{rest\ 1247}#)) + (#{first\ 1250}# (cdr #{first\ 1246}#)) + (#{rest\ 1251}# + (map cdr #{rest\ 1247}#))) + (if (null? #{first\ 1250}#) + (apply #{f\ 1239}# + (cons #{x\ 1248}# #{xr\ 1249}#)) + (if (apply #{f\ 1239}# + (cons #{x\ 1248}# #{xr\ 1249}#)) + (#{andmap\ 1245}# + #{first\ 1250}# + #{rest\ 1251}#) + #f)))))) + (#{andmap\ 1245}# #{first\ 1238}# #{rest\ 1237}#)))))))) + (letrec ((#{lambda-var-list\ 1345}# + (lambda (#{vars\ 1469}#) + (letrec ((#{lvl\ 1470}# + (lambda (#{vars\ 1471}# #{ls\ 1472}# #{w\ 1473}#) + (if (pair? #{vars\ 1471}#) + (#{lvl\ 1470}# + (cdr #{vars\ 1471}#) + (cons (#{wrap\ 1325}# + (car #{vars\ 1471}#) + #{w\ 1473}# + #f) + #{ls\ 1472}#) + #{w\ 1473}#) + (if (#{id?\ 1297}# #{vars\ 1471}#) + (cons (#{wrap\ 1325}# + #{vars\ 1471}# + #{w\ 1473}# + #f) + #{ls\ 1472}#) + (if (null? #{vars\ 1471}#) + #{ls\ 1472}# + (if (#{syntax-object?\ 1281}# #{vars\ 1471}#) + (#{lvl\ 1470}# + (#{syntax-object-expression\ 1282}# + #{vars\ 1471}#) + #{ls\ 1472}# + (#{join-wraps\ 1316}# + #{w\ 1473}# + (#{syntax-object-wrap\ 1283}# + #{vars\ 1471}#))) + (cons #{vars\ 1471}# #{ls\ 1472}#)))))))) + (#{lvl\ 1470}# + #{vars\ 1469}# + '() + '(()))))) + (#{gen-var\ 1344}# + (lambda (#{id\ 1474}#) + (let ((#{id\ 1475}# + (if (#{syntax-object?\ 1281}# #{id\ 1474}#) + (#{syntax-object-expression\ 1282}# #{id\ 1474}#) + #{id\ 1474}#))) + (gensym + (string-append (symbol->string #{id\ 1475}#) " "))))) + (#{strip\ 1343}# + (lambda (#{x\ 1476}# #{w\ 1477}#) + (if (memq 'top + (#{wrap-marks\ 1300}# #{w\ 1477}#)) + #{x\ 1476}# + (letrec ((#{f\ 1478}# + (lambda (#{x\ 1479}#) + (if (#{syntax-object?\ 1281}# #{x\ 1479}#) + (#{strip\ 1343}# + (#{syntax-object-expression\ 1282}# + #{x\ 1479}#) + (#{syntax-object-wrap\ 1283}# #{x\ 1479}#)) + (if (pair? #{x\ 1479}#) + (let ((#{a\ 1480}# + (#{f\ 1478}# (car #{x\ 1479}#))) + (#{d\ 1481}# + (#{f\ 1478}# (cdr #{x\ 1479}#)))) + (if (if (eq? #{a\ 1480}# (car #{x\ 1479}#)) + (eq? #{d\ 1481}# (cdr #{x\ 1479}#)) + #f) + #{x\ 1479}# + (cons #{a\ 1480}# #{d\ 1481}#))) + (if (vector? #{x\ 1479}#) + (let ((#{old\ 1482}# + (vector->list #{x\ 1479}#))) + (let ((#{new\ 1483}# + (map #{f\ 1478}# #{old\ 1482}#))) + (if (#{and-map*\ 1199}# + eq? + #{old\ 1482}# + #{new\ 1483}#) + #{x\ 1479}# + (list->vector #{new\ 1483}#)))) + #{x\ 1479}#)))))) + (#{f\ 1478}# #{x\ 1476}#))))) + (#{ellipsis?\ 1342}# + (lambda (#{x\ 1484}#) + (if (#{nonsymbol-id?\ 1296}# #{x\ 1484}#) + (#{free-id=?\ 1320}# + #{x\ 1484}# + '#(syntax-object + ... + ((top) + #(ribcage () () ()) + #(ribcage () () ()) + #(ribcage #(x) #((top)) #("i")) + #(ribcage + (lambda-var-list + gen-var + strip + ellipsis? + chi-void + eval-local-transformer + chi-local-syntax + chi-lambda-clause + chi-body + chi-macro + chi-application + chi-expr + chi + chi-top + syntax-type + chi-when-list + chi-install-global + chi-top-sequence + chi-sequence + source-wrap + wrap + bound-id-member? + distinct-bound-ids? + valid-bound-ids? + bound-id=? + free-id=? + id-var-name + same-marks? + join-marks + join-wraps + smart-append + make-binding-wrap + extend-ribcage! + make-empty-ribcage + new-mark + anti-mark + the-anti-mark + top-marked? + top-wrap + empty-wrap + set-ribcage-labels! + set-ribcage-marks! + set-ribcage-symnames! + ribcage-labels + ribcage-marks + ribcage-symnames + ribcage? + make-ribcage + gen-labels + gen-label + make-rename + rename-marks + rename-new + rename-old + subst-rename? + wrap-subst + wrap-marks + make-wrap + id-sym-name&marks + id-sym-name + id? + nonsymbol-id? + global-extend + lookup + macros-only-env + extend-var-env + extend-env + null-env + binding-value + binding-type + make-binding + arg-check + source-annotation + no-source + set-syntax-object-module! + set-syntax-object-wrap! + set-syntax-object-expression! + syntax-object-module + syntax-object-wrap + syntax-object-expression + syntax-object? + make-syntax-object + build-lexical-var + build-letrec + build-named-let + build-let + build-sequence + build-data + build-primref + build-lambda + build-global-definition + maybe-name-value! + build-global-assignment + build-global-reference + analyze-variable + build-lexical-assignment + build-lexical-reference + build-conditional + build-application + build-void + decorate-source + get-global-definition-hook + put-global-definition-hook + gensym-hook + local-eval-hook + top-level-eval-hook + fx< + fx= + fx- + fx+ + *mode* + noexpand) + ((top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top)) + ("i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i")) + #(ribcage + (define-structure and-map*) + ((top) (top)) + ("i" "i"))) + (hygiene guile))) + #f))) + (#{chi-void\ 1341}# + (lambda () (#{build-void\ 1263}# #f))) + (#{eval-local-transformer\ 1340}# + (lambda (#{expanded\ 1485}# #{mod\ 1486}#) + (let ((#{p\ 1487}# + (#{local-eval-hook\ 1259}# + #{expanded\ 1485}# + #{mod\ 1486}#))) + (if (procedure? #{p\ 1487}#) + #{p\ 1487}# + (syntax-violation + #f + "nonprocedure transformer" + #{p\ 1487}#))))) + (#{chi-local-syntax\ 1339}# + (lambda (#{rec?\ 1488}# + #{e\ 1489}# + #{r\ 1490}# + #{w\ 1491}# + #{s\ 1492}# + #{mod\ 1493}# + #{k\ 1494}#) + ((lambda (#{tmp\ 1495}#) + ((lambda (#{tmp\ 1496}#) + (if #{tmp\ 1496}# + (apply (lambda (#{_\ 1497}# + #{id\ 1498}# + #{val\ 1499}# + #{e1\ 1500}# + #{e2\ 1501}#) + (let ((#{ids\ 1502}# #{id\ 1498}#)) + (if (not (#{valid-bound-ids?\ 1322}# + #{ids\ 1502}#)) + (syntax-violation + #f + "duplicate bound keyword" + #{e\ 1489}#) + (let ((#{labels\ 1504}# + (#{gen-labels\ 1303}# + #{ids\ 1502}#))) + (let ((#{new-w\ 1505}# + (#{make-binding-wrap\ 1314}# + #{ids\ 1502}# + #{labels\ 1504}# + #{w\ 1491}#))) + (#{k\ 1494}# + (cons #{e1\ 1500}# #{e2\ 1501}#) + (#{extend-env\ 1291}# + #{labels\ 1504}# + (let ((#{w\ 1507}# + (if #{rec?\ 1488}# + #{new-w\ 1505}# + #{w\ 1491}#)) + (#{trans-r\ 1508}# + (#{macros-only-env\ 1293}# + #{r\ 1490}#))) + (map (lambda (#{x\ 1509}#) + (cons 'macro + (#{eval-local-transformer\ 1340}# + (#{chi\ 1333}# + #{x\ 1509}# + #{trans-r\ 1508}# + #{w\ 1507}# + #{mod\ 1493}#) + #{mod\ 1493}#))) + #{val\ 1499}#)) + #{r\ 1490}#) + #{new-w\ 1505}# + #{s\ 1492}# + #{mod\ 1493}#)))))) + #{tmp\ 1496}#) + ((lambda (#{_\ 1511}#) + (syntax-violation + #f + "bad local syntax definition" + (#{source-wrap\ 1326}# + #{e\ 1489}# + #{w\ 1491}# + #{s\ 1492}# + #{mod\ 1493}#))) + #{tmp\ 1495}#))) + ($sc-dispatch + #{tmp\ 1495}# + '(any #(each (any any)) any . each-any)))) + #{e\ 1489}#))) + (#{chi-lambda-clause\ 1338}# + (lambda (#{e\ 1512}# + #{docstring\ 1513}# + #{c\ 1514}# + #{r\ 1515}# + #{w\ 1516}# + #{mod\ 1517}# + #{k\ 1518}#) + ((lambda (#{tmp\ 1519}#) + ((lambda (#{tmp\ 1520}#) + (if (if #{tmp\ 1520}# + (apply (lambda (#{args\ 1521}# + #{doc\ 1522}# + #{e1\ 1523}# + #{e2\ 1524}#) + (if (string? (syntax->datum #{doc\ 1522}#)) + (not #{docstring\ 1513}#) + #f)) + #{tmp\ 1520}#) + #f) + (apply (lambda (#{args\ 1525}# + #{doc\ 1526}# + #{e1\ 1527}# + #{e2\ 1528}#) + (#{chi-lambda-clause\ 1338}# + #{e\ 1512}# + #{doc\ 1526}# + (cons #{args\ 1525}# + (cons #{e1\ 1527}# #{e2\ 1528}#)) + #{r\ 1515}# + #{w\ 1516}# + #{mod\ 1517}# + #{k\ 1518}#)) + #{tmp\ 1520}#) + ((lambda (#{tmp\ 1530}#) + (if #{tmp\ 1530}# + (apply (lambda (#{id\ 1531}# + #{e1\ 1532}# + #{e2\ 1533}#) + (let ((#{ids\ 1534}# #{id\ 1531}#)) + (if (not (#{valid-bound-ids?\ 1322}# + #{ids\ 1534}#)) + (syntax-violation + 'lambda + "invalid parameter list" + #{e\ 1512}#) + (let ((#{labels\ 1536}# + (#{gen-labels\ 1303}# + #{ids\ 1534}#)) + (#{new-vars\ 1537}# + (map #{gen-var\ 1344}# + #{ids\ 1534}#))) + (#{k\ 1518}# + (map syntax->datum #{ids\ 1534}#) + #{new-vars\ 1537}# + (if #{docstring\ 1513}# + (syntax->datum + #{docstring\ 1513}#) + #f) + (#{chi-body\ 1337}# + (cons #{e1\ 1532}# #{e2\ 1533}#) + #{e\ 1512}# + (#{extend-var-env\ 1292}# + #{labels\ 1536}# + #{new-vars\ 1537}# + #{r\ 1515}#) + (#{make-binding-wrap\ 1314}# + #{ids\ 1534}# + #{labels\ 1536}# + #{w\ 1516}#) + #{mod\ 1517}#)))))) + #{tmp\ 1530}#) + ((lambda (#{tmp\ 1539}#) + (if #{tmp\ 1539}# + (apply (lambda (#{ids\ 1540}# + #{e1\ 1541}# + #{e2\ 1542}#) + (let ((#{old-ids\ 1543}# + (#{lambda-var-list\ 1345}# + #{ids\ 1540}#))) + (if (not (#{valid-bound-ids?\ 1322}# + #{old-ids\ 1543}#)) + (syntax-violation + 'lambda + "invalid parameter list" + #{e\ 1512}#) + (let ((#{labels\ 1544}# + (#{gen-labels\ 1303}# + #{old-ids\ 1543}#)) + (#{new-vars\ 1545}# + (map #{gen-var\ 1344}# + #{old-ids\ 1543}#))) + (#{k\ 1518}# + (letrec ((#{f\ 1546}# + (lambda (#{ls1\ 1547}# + #{ls2\ 1548}#) + (if (null? #{ls1\ 1547}#) + (syntax->datum + #{ls2\ 1548}#) + (#{f\ 1546}# + (cdr #{ls1\ 1547}#) + (cons (syntax->datum + (car #{ls1\ 1547}#)) + #{ls2\ 1548}#)))))) + (#{f\ 1546}# + (cdr #{old-ids\ 1543}#) + (car #{old-ids\ 1543}#))) + (letrec ((#{f\ 1549}# + (lambda (#{ls1\ 1550}# + #{ls2\ 1551}#) + (if (null? #{ls1\ 1550}#) + #{ls2\ 1551}# + (#{f\ 1549}# + (cdr #{ls1\ 1550}#) + (cons (car #{ls1\ 1550}#) + #{ls2\ 1551}#)))))) + (#{f\ 1549}# + (cdr #{new-vars\ 1545}#) + (car #{new-vars\ 1545}#))) + (if #{docstring\ 1513}# + (syntax->datum + #{docstring\ 1513}#) + #f) + (#{chi-body\ 1337}# + (cons #{e1\ 1541}# + #{e2\ 1542}#) + #{e\ 1512}# + (#{extend-var-env\ 1292}# + #{labels\ 1544}# + #{new-vars\ 1545}# + #{r\ 1515}#) + (#{make-binding-wrap\ 1314}# + #{old-ids\ 1543}# + #{labels\ 1544}# + #{w\ 1516}#) + #{mod\ 1517}#)))))) + #{tmp\ 1539}#) + ((lambda (#{_\ 1553}#) + (syntax-violation + 'lambda + "bad lambda" + #{e\ 1512}#)) + #{tmp\ 1519}#))) + ($sc-dispatch + #{tmp\ 1519}# + '(any any . each-any))))) + ($sc-dispatch + #{tmp\ 1519}# + '(each-any any . each-any))))) + ($sc-dispatch + #{tmp\ 1519}# + '(any any any . each-any)))) + #{c\ 1514}#))) + (#{chi-body\ 1337}# + (lambda (#{body\ 1554}# + #{outer-form\ 1555}# + #{r\ 1556}# + #{w\ 1557}# + #{mod\ 1558}#) + (let ((#{r\ 1559}# + (cons '("placeholder" placeholder) + #{r\ 1556}#))) + (let ((#{ribcage\ 1560}# + (#{make-ribcage\ 1304}# + '() + '() + '()))) + (let ((#{w\ 1561}# + (#{make-wrap\ 1299}# + (#{wrap-marks\ 1300}# #{w\ 1557}#) + (cons #{ribcage\ 1560}# + (#{wrap-subst\ 1301}# #{w\ 1557}#))))) + (letrec ((#{parse\ 1562}# + (lambda (#{body\ 1563}# + #{ids\ 1564}# + #{labels\ 1565}# + #{var-ids\ 1566}# + #{vars\ 1567}# + #{vals\ 1568}# + #{bindings\ 1569}#) + (if (null? #{body\ 1563}#) + (syntax-violation + #f + "no expressions in body" + #{outer-form\ 1555}#) + (let ((#{e\ 1571}# (cdar #{body\ 1563}#)) + (#{er\ 1572}# (caar #{body\ 1563}#))) + (call-with-values + (lambda () + (#{syntax-type\ 1331}# + #{e\ 1571}# + #{er\ 1572}# + '(()) + (#{source-annotation\ 1288}# + #{er\ 1572}#) + #{ribcage\ 1560}# + #{mod\ 1558}# + #f)) + (lambda (#{type\ 1573}# + #{value\ 1574}# + #{e\ 1575}# + #{w\ 1576}# + #{s\ 1577}# + #{mod\ 1578}#) + (if (memv #{type\ 1573}# + '(define-form)) + (let ((#{id\ 1579}# + (#{wrap\ 1325}# + #{value\ 1574}# + #{w\ 1576}# + #{mod\ 1578}#)) + (#{label\ 1580}# + (#{gen-label\ 1302}#))) + (let ((#{var\ 1581}# + (#{gen-var\ 1344}# + #{id\ 1579}#))) + (begin + (#{extend-ribcage!\ 1313}# + #{ribcage\ 1560}# + #{id\ 1579}# + #{label\ 1580}#) + (#{parse\ 1562}# + (cdr #{body\ 1563}#) + (cons #{id\ 1579}# + #{ids\ 1564}#) + (cons #{label\ 1580}# + #{labels\ 1565}#) + (cons #{id\ 1579}# + #{var-ids\ 1566}#) + (cons #{var\ 1581}# + #{vars\ 1567}#) + (cons (cons #{er\ 1572}# + (#{wrap\ 1325}# + #{e\ 1575}# + #{w\ 1576}# + #{mod\ 1578}#)) + #{vals\ 1568}#) + (cons (cons 'lexical + #{var\ 1581}#) + #{bindings\ 1569}#))))) + (if (memv #{type\ 1573}# + '(define-syntax-form)) + (let ((#{id\ 1582}# + (#{wrap\ 1325}# + #{value\ 1574}# + #{w\ 1576}# + #{mod\ 1578}#)) + (#{label\ 1583}# + (#{gen-label\ 1302}#))) + (begin + (#{extend-ribcage!\ 1313}# + #{ribcage\ 1560}# + #{id\ 1582}# + #{label\ 1583}#) + (#{parse\ 1562}# + (cdr #{body\ 1563}#) + (cons #{id\ 1582}# + #{ids\ 1564}#) + (cons #{label\ 1583}# + #{labels\ 1565}#) + #{var-ids\ 1566}# + #{vars\ 1567}# + #{vals\ 1568}# + (cons (cons 'macro + (cons #{er\ 1572}# + (#{wrap\ 1325}# + #{e\ 1575}# + #{w\ 1576}# + #{mod\ 1578}#))) + #{bindings\ 1569}#)))) + (if (memv #{type\ 1573}# + '(begin-form)) + ((lambda (#{tmp\ 1584}#) + ((lambda (#{tmp\ 1585}#) + (if #{tmp\ 1585}# + (apply (lambda (#{_\ 1586}# + #{e1\ 1587}#) + (#{parse\ 1562}# + (letrec ((#{f\ 1588}# + (lambda (#{forms\ 1589}#) + (if (null? #{forms\ 1589}#) + (cdr #{body\ 1563}#) + (cons (cons #{er\ 1572}# + (#{wrap\ 1325}# + (car #{forms\ 1589}#) + #{w\ 1576}# + #{mod\ 1578}#)) + (#{f\ 1588}# + (cdr #{forms\ 1589}#))))))) + (#{f\ 1588}# + #{e1\ 1587}#)) + #{ids\ 1564}# + #{labels\ 1565}# + #{var-ids\ 1566}# + #{vars\ 1567}# + #{vals\ 1568}# + #{bindings\ 1569}#)) + #{tmp\ 1585}#) + (syntax-violation + #f + "source expression failed to match any pattern" + #{tmp\ 1584}#))) + ($sc-dispatch + #{tmp\ 1584}# + '(any . each-any)))) + #{e\ 1575}#) + (if (memv #{type\ 1573}# + '(local-syntax-form)) + (#{chi-local-syntax\ 1339}# + #{value\ 1574}# + #{e\ 1575}# + #{er\ 1572}# + #{w\ 1576}# + #{s\ 1577}# + #{mod\ 1578}# + (lambda (#{forms\ 1591}# + #{er\ 1592}# + #{w\ 1593}# + #{s\ 1594}# + #{mod\ 1595}#) + (#{parse\ 1562}# + (letrec ((#{f\ 1596}# + (lambda (#{forms\ 1597}#) + (if (null? #{forms\ 1597}#) + (cdr #{body\ 1563}#) + (cons (cons #{er\ 1592}# + (#{wrap\ 1325}# + (car #{forms\ 1597}#) + #{w\ 1593}# + #{mod\ 1595}#)) + (#{f\ 1596}# + (cdr #{forms\ 1597}#))))))) + (#{f\ 1596}# + #{forms\ 1591}#)) + #{ids\ 1564}# + #{labels\ 1565}# + #{var-ids\ 1566}# + #{vars\ 1567}# + #{vals\ 1568}# + #{bindings\ 1569}#))) + (if (null? #{ids\ 1564}#) + (#{build-sequence\ 1276}# + #f + (map (lambda (#{x\ 1598}#) + (#{chi\ 1333}# + (cdr #{x\ 1598}#) + (car #{x\ 1598}#) + '(()) + #{mod\ 1578}#)) + (cons (cons #{er\ 1572}# + (#{source-wrap\ 1326}# + #{e\ 1575}# + #{w\ 1576}# + #{s\ 1577}# + #{mod\ 1578}#)) + (cdr #{body\ 1563}#)))) + (begin + (if (not (#{valid-bound-ids?\ 1322}# + #{ids\ 1564}#)) + (syntax-violation + #f + "invalid or duplicate identifier in definition" + #{outer-form\ 1555}#)) + (letrec ((#{loop\ 1599}# + (lambda (#{bs\ 1600}# + #{er-cache\ 1601}# + #{r-cache\ 1602}#) + (if (not (null? #{bs\ 1600}#)) + (let ((#{b\ 1603}# + (car #{bs\ 1600}#))) + (if (eq? (car #{b\ 1603}#) + 'macro) + (let ((#{er\ 1604}# + (cadr #{b\ 1603}#))) + (let ((#{r-cache\ 1605}# + (if (eq? #{er\ 1604}# + #{er-cache\ 1601}#) + #{r-cache\ 1602}# + (#{macros-only-env\ 1293}# + #{er\ 1604}#)))) + (begin + (set-cdr! + #{b\ 1603}# + (#{eval-local-transformer\ 1340}# + (#{chi\ 1333}# + (cddr #{b\ 1603}#) + #{r-cache\ 1605}# + '(()) + #{mod\ 1578}#) + #{mod\ 1578}#)) + (#{loop\ 1599}# + (cdr #{bs\ 1600}#) + #{er\ 1604}# + #{r-cache\ 1605}#)))) + (#{loop\ 1599}# + (cdr #{bs\ 1600}#) + #{er-cache\ 1601}# + #{r-cache\ 1602}#))))))) + (#{loop\ 1599}# + #{bindings\ 1569}# + #f + #f)) + (set-cdr! + #{r\ 1559}# + (#{extend-env\ 1291}# + #{labels\ 1565}# + #{bindings\ 1569}# + (cdr #{r\ 1559}#))) + (#{build-letrec\ 1279}# + #f + (map syntax->datum + #{var-ids\ 1566}#) + #{vars\ 1567}# + (map (lambda (#{x\ 1606}#) + (#{chi\ 1333}# + (cdr #{x\ 1606}#) + (car #{x\ 1606}#) + '(()) + #{mod\ 1578}#)) + #{vals\ 1568}#) + (#{build-sequence\ 1276}# + #f + (map (lambda (#{x\ 1607}#) + (#{chi\ 1333}# + (cdr #{x\ 1607}#) + (car #{x\ 1607}#) + '(()) + #{mod\ 1578}#)) + (cons (cons #{er\ 1572}# + (#{source-wrap\ 1326}# + #{e\ 1575}# + #{w\ 1576}# + #{s\ 1577}# + #{mod\ 1578}#)) + (cdr #{body\ 1563}#)))))))))))))))))) + (#{parse\ 1562}# + (map (lambda (#{x\ 1570}#) + (cons #{r\ 1559}# + (#{wrap\ 1325}# + #{x\ 1570}# + #{w\ 1561}# + #{mod\ 1558}#))) + #{body\ 1554}#) + '() + '() + '() + '() + '() + '()))))))) + (#{chi-macro\ 1336}# + (lambda (#{p\ 1608}# + #{e\ 1609}# + #{r\ 1610}# + #{w\ 1611}# + #{rib\ 1612}# + #{mod\ 1613}#) + (letrec ((#{rebuild-macro-output\ 1614}# + (lambda (#{x\ 1615}# #{m\ 1616}#) + (if (pair? #{x\ 1615}#) + (cons (#{rebuild-macro-output\ 1614}# + (car #{x\ 1615}#) + #{m\ 1616}#) + (#{rebuild-macro-output\ 1614}# + (cdr #{x\ 1615}#) + #{m\ 1616}#)) + (if (#{syntax-object?\ 1281}# #{x\ 1615}#) + (let ((#{w\ 1617}# + (#{syntax-object-wrap\ 1283}# + #{x\ 1615}#))) + (let ((#{ms\ 1618}# + (#{wrap-marks\ 1300}# #{w\ 1617}#)) + (#{s\ 1619}# + (#{wrap-subst\ 1301}# #{w\ 1617}#))) + (if (if (pair? #{ms\ 1618}#) + (eq? (car #{ms\ 1618}#) #f) + #f) + (#{make-syntax-object\ 1280}# + (#{syntax-object-expression\ 1282}# + #{x\ 1615}#) + (#{make-wrap\ 1299}# + (cdr #{ms\ 1618}#) + (if #{rib\ 1612}# + (cons #{rib\ 1612}# + (cdr #{s\ 1619}#)) + (cdr #{s\ 1619}#))) + (#{syntax-object-module\ 1284}# + #{x\ 1615}#)) + (#{make-syntax-object\ 1280}# + (#{syntax-object-expression\ 1282}# + #{x\ 1615}#) + (#{make-wrap\ 1299}# + (cons #{m\ 1616}# #{ms\ 1618}#) + (if #{rib\ 1612}# + (cons #{rib\ 1612}# + (cons 'shift + #{s\ 1619}#)) + (cons (quote shift) #{s\ 1619}#))) + (let ((#{pmod\ 1620}# + (procedure-module + #{p\ 1608}#))) + (if #{pmod\ 1620}# + (cons 'hygiene + (module-name #{pmod\ 1620}#)) + '(hygiene guile))))))) + (if (vector? #{x\ 1615}#) + (let ((#{n\ 1621}# + (vector-length #{x\ 1615}#))) + (let ((#{v\ 1622}# + (make-vector #{n\ 1621}#))) + (letrec ((#{loop\ 1623}# + (lambda (#{i\ 1624}#) + (if (#{fx=\ 1256}# + #{i\ 1624}# + #{n\ 1621}#) + (begin + (if #f #f) + #{v\ 1622}#) + (begin + (vector-set! + #{v\ 1622}# + #{i\ 1624}# + (#{rebuild-macro-output\ 1614}# + (vector-ref + #{x\ 1615}# + #{i\ 1624}#) + #{m\ 1616}#)) + (#{loop\ 1623}# + (#{fx+\ 1254}# + #{i\ 1624}# + 1))))))) + (#{loop\ 1623}# 0)))) + (if (symbol? #{x\ 1615}#) + (syntax-violation + #f + "encountered raw symbol in macro output" + (#{source-wrap\ 1326}# + #{e\ 1609}# + #{w\ 1611}# + s + #{mod\ 1613}#) + #{x\ 1615}#) + #{x\ 1615}#))))))) + (#{rebuild-macro-output\ 1614}# + (#{p\ 1608}# + (#{wrap\ 1325}# + #{e\ 1609}# + (#{anti-mark\ 1312}# #{w\ 1611}#) + #{mod\ 1613}#)) + (string #\m))))) + (#{chi-application\ 1335}# + (lambda (#{x\ 1625}# + #{e\ 1626}# + #{r\ 1627}# + #{w\ 1628}# + #{s\ 1629}# + #{mod\ 1630}#) + ((lambda (#{tmp\ 1631}#) + ((lambda (#{tmp\ 1632}#) + (if #{tmp\ 1632}# + (apply (lambda (#{e0\ 1633}# #{e1\ 1634}#) + (#{build-application\ 1264}# + #{s\ 1629}# + #{x\ 1625}# + (map (lambda (#{e\ 1635}#) + (#{chi\ 1333}# + #{e\ 1635}# + #{r\ 1627}# + #{w\ 1628}# + #{mod\ 1630}#)) + #{e1\ 1634}#))) + #{tmp\ 1632}#) + (syntax-violation + #f + "source expression failed to match any pattern" + #{tmp\ 1631}#))) + ($sc-dispatch + #{tmp\ 1631}# + '(any . each-any)))) + #{e\ 1626}#))) + (#{chi-expr\ 1334}# + (lambda (#{type\ 1637}# + #{value\ 1638}# + #{e\ 1639}# + #{r\ 1640}# + #{w\ 1641}# + #{s\ 1642}# + #{mod\ 1643}#) + (if (memv #{type\ 1637}# (quote (lexical))) + (#{build-lexical-reference\ 1266}# + 'value + #{s\ 1642}# + #{e\ 1639}# + #{value\ 1638}#) + (if (memv #{type\ 1637}# (quote (core core-form))) + (#{value\ 1638}# + #{e\ 1639}# + #{r\ 1640}# + #{w\ 1641}# + #{s\ 1642}# + #{mod\ 1643}#) + (if (memv #{type\ 1637}# (quote (module-ref))) + (call-with-values + (lambda () (#{value\ 1638}# #{e\ 1639}#)) + (lambda (#{id\ 1644}# #{mod\ 1645}#) + (#{build-global-reference\ 1269}# + #{s\ 1642}# + #{id\ 1644}# + #{mod\ 1645}#))) + (if (memv #{type\ 1637}# (quote (lexical-call))) + (#{chi-application\ 1335}# + (#{build-lexical-reference\ 1266}# + 'fun + (#{source-annotation\ 1288}# (car #{e\ 1639}#)) + (car #{e\ 1639}#) + #{value\ 1638}#) + #{e\ 1639}# + #{r\ 1640}# + #{w\ 1641}# + #{s\ 1642}# + #{mod\ 1643}#) + (if (memv #{type\ 1637}# (quote (global-call))) + (#{chi-application\ 1335}# + (#{build-global-reference\ 1269}# + (#{source-annotation\ 1288}# (car #{e\ 1639}#)) + (if (#{syntax-object?\ 1281}# #{value\ 1638}#) + (#{syntax-object-expression\ 1282}# + #{value\ 1638}#) + #{value\ 1638}#) + (if (#{syntax-object?\ 1281}# #{value\ 1638}#) + (#{syntax-object-module\ 1284}# #{value\ 1638}#) + #{mod\ 1643}#)) + #{e\ 1639}# + #{r\ 1640}# + #{w\ 1641}# + #{s\ 1642}# + #{mod\ 1643}#) + (if (memv #{type\ 1637}# (quote (constant))) + (#{build-data\ 1275}# + #{s\ 1642}# + (#{strip\ 1343}# + (#{source-wrap\ 1326}# + #{e\ 1639}# + #{w\ 1641}# + #{s\ 1642}# + #{mod\ 1643}#) + '(()))) + (if (memv #{type\ 1637}# (quote (global))) + (#{build-global-reference\ 1269}# + #{s\ 1642}# + #{value\ 1638}# + #{mod\ 1643}#) + (if (memv #{type\ 1637}# (quote (call))) + (#{chi-application\ 1335}# + (#{chi\ 1333}# + (car #{e\ 1639}#) + #{r\ 1640}# + #{w\ 1641}# + #{mod\ 1643}#) + #{e\ 1639}# + #{r\ 1640}# + #{w\ 1641}# + #{s\ 1642}# + #{mod\ 1643}#) + (if (memv #{type\ 1637}# (quote (begin-form))) + ((lambda (#{tmp\ 1646}#) + ((lambda (#{tmp\ 1647}#) + (if #{tmp\ 1647}# + (apply (lambda (#{_\ 1648}# + #{e1\ 1649}# + #{e2\ 1650}#) + (#{chi-sequence\ 1327}# + (cons #{e1\ 1649}# + #{e2\ 1650}#) + #{r\ 1640}# + #{w\ 1641}# + #{s\ 1642}# + #{mod\ 1643}#)) + #{tmp\ 1647}#) + (syntax-violation + #f + "source expression failed to match any pattern" + #{tmp\ 1646}#))) + ($sc-dispatch + #{tmp\ 1646}# + '(any any . each-any)))) + #{e\ 1639}#) + (if (memv #{type\ 1637}# + '(local-syntax-form)) + (#{chi-local-syntax\ 1339}# + #{value\ 1638}# + #{e\ 1639}# + #{r\ 1640}# + #{w\ 1641}# + #{s\ 1642}# + #{mod\ 1643}# + #{chi-sequence\ 1327}#) + (if (memv #{type\ 1637}# + '(eval-when-form)) + ((lambda (#{tmp\ 1652}#) + ((lambda (#{tmp\ 1653}#) + (if #{tmp\ 1653}# + (apply (lambda (#{_\ 1654}# + #{x\ 1655}# + #{e1\ 1656}# + #{e2\ 1657}#) + (let ((#{when-list\ 1658}# + (#{chi-when-list\ 1330}# + #{e\ 1639}# + #{x\ 1655}# + #{w\ 1641}#))) + (if (memq 'eval + #{when-list\ 1658}#) + (#{chi-sequence\ 1327}# + (cons #{e1\ 1656}# + #{e2\ 1657}#) + #{r\ 1640}# + #{w\ 1641}# + #{s\ 1642}# + #{mod\ 1643}#) + (#{chi-void\ 1341}#)))) + #{tmp\ 1653}#) + (syntax-violation + #f + "source expression failed to match any pattern" + #{tmp\ 1652}#))) + ($sc-dispatch + #{tmp\ 1652}# + '(any each-any any . each-any)))) + #{e\ 1639}#) + (if (memv #{type\ 1637}# + '(define-form + define-syntax-form)) + (syntax-violation + #f + "definition in expression context" + #{e\ 1639}# + (#{wrap\ 1325}# + #{value\ 1638}# + #{w\ 1641}# + #{mod\ 1643}#)) + (if (memv #{type\ 1637}# + '(syntax)) + (syntax-violation + #f + "reference to pattern variable outside syntax form" + (#{source-wrap\ 1326}# + #{e\ 1639}# + #{w\ 1641}# + #{s\ 1642}# + #{mod\ 1643}#)) + (if (memv #{type\ 1637}# + '(displaced-lexical)) + (syntax-violation + #f + "reference to identifier outside its scope" + (#{source-wrap\ 1326}# + #{e\ 1639}# + #{w\ 1641}# + #{s\ 1642}# + #{mod\ 1643}#)) + (syntax-violation + #f + "unexpected syntax" + (#{source-wrap\ 1326}# + #{e\ 1639}# + #{w\ 1641}# + #{s\ 1642}# + #{mod\ 1643}#)))))))))))))))))) + (#{chi\ 1333}# + (lambda (#{e\ 1661}# + #{r\ 1662}# + #{w\ 1663}# + #{mod\ 1664}#) + (call-with-values + (lambda () + (#{syntax-type\ 1331}# + #{e\ 1661}# + #{r\ 1662}# + #{w\ 1663}# + (#{source-annotation\ 1288}# #{e\ 1661}#) + #f + #{mod\ 1664}# + #f)) + (lambda (#{type\ 1665}# + #{value\ 1666}# + #{e\ 1667}# + #{w\ 1668}# + #{s\ 1669}# + #{mod\ 1670}#) + (#{chi-expr\ 1334}# + #{type\ 1665}# + #{value\ 1666}# + #{e\ 1667}# + #{r\ 1662}# + #{w\ 1668}# + #{s\ 1669}# + #{mod\ 1670}#))))) + (#{chi-top\ 1332}# + (lambda (#{e\ 1671}# + #{r\ 1672}# + #{w\ 1673}# + #{m\ 1674}# + #{esew\ 1675}# + #{mod\ 1676}#) + (call-with-values + (lambda () + (#{syntax-type\ 1331}# + #{e\ 1671}# + #{r\ 1672}# + #{w\ 1673}# + (#{source-annotation\ 1288}# #{e\ 1671}#) + #f + #{mod\ 1676}# + #f)) + (lambda (#{type\ 1684}# + #{value\ 1685}# + #{e\ 1686}# + #{w\ 1687}# + #{s\ 1688}# + #{mod\ 1689}#) + (if (memv #{type\ 1684}# (quote (begin-form))) + ((lambda (#{tmp\ 1690}#) + ((lambda (#{tmp\ 1691}#) + (if #{tmp\ 1691}# + (apply (lambda (#{_\ 1692}#) (#{chi-void\ 1341}#)) + #{tmp\ 1691}#) + ((lambda (#{tmp\ 1693}#) + (if #{tmp\ 1693}# + (apply (lambda (#{_\ 1694}# + #{e1\ 1695}# + #{e2\ 1696}#) + (#{chi-top-sequence\ 1328}# + (cons #{e1\ 1695}# #{e2\ 1696}#) + #{r\ 1672}# + #{w\ 1687}# + #{s\ 1688}# + #{m\ 1674}# + #{esew\ 1675}# + #{mod\ 1689}#)) + #{tmp\ 1693}#) + (syntax-violation + #f + "source expression failed to match any pattern" + #{tmp\ 1690}#))) + ($sc-dispatch + #{tmp\ 1690}# + '(any any . each-any))))) + ($sc-dispatch #{tmp\ 1690}# (quote (any))))) + #{e\ 1686}#) + (if (memv #{type\ 1684}# (quote (local-syntax-form))) + (#{chi-local-syntax\ 1339}# + #{value\ 1685}# + #{e\ 1686}# + #{r\ 1672}# + #{w\ 1687}# + #{s\ 1688}# + #{mod\ 1689}# + (lambda (#{body\ 1698}# + #{r\ 1699}# + #{w\ 1700}# + #{s\ 1701}# + #{mod\ 1702}#) + (#{chi-top-sequence\ 1328}# + #{body\ 1698}# + #{r\ 1699}# + #{w\ 1700}# + #{s\ 1701}# + #{m\ 1674}# + #{esew\ 1675}# + #{mod\ 1702}#))) + (if (memv #{type\ 1684}# (quote (eval-when-form))) + ((lambda (#{tmp\ 1703}#) + ((lambda (#{tmp\ 1704}#) + (if #{tmp\ 1704}# + (apply (lambda (#{_\ 1705}# + #{x\ 1706}# + #{e1\ 1707}# + #{e2\ 1708}#) + (let ((#{when-list\ 1709}# + (#{chi-when-list\ 1330}# + #{e\ 1686}# + #{x\ 1706}# + #{w\ 1687}#)) + (#{body\ 1710}# + (cons #{e1\ 1707}# + #{e2\ 1708}#))) + (if (eq? #{m\ 1674}# (quote e)) + (if (memq 'eval + #{when-list\ 1709}#) + (#{chi-top-sequence\ 1328}# + #{body\ 1710}# + #{r\ 1672}# + #{w\ 1687}# + #{s\ 1688}# + 'e + '(eval) + #{mod\ 1689}#) + (#{chi-void\ 1341}#)) + (if (memq 'load + #{when-list\ 1709}#) + (if (let ((#{t\ 1713}# + (memq 'compile + #{when-list\ 1709}#))) + (if #{t\ 1713}# + #{t\ 1713}# + (if (eq? #{m\ 1674}# + 'c&e) + (memq 'eval + #{when-list\ 1709}#) + #f))) + (#{chi-top-sequence\ 1328}# + #{body\ 1710}# + #{r\ 1672}# + #{w\ 1687}# + #{s\ 1688}# + 'c&e + '(compile load) + #{mod\ 1689}#) + (if (memq #{m\ 1674}# + '(c c&e)) + (#{chi-top-sequence\ 1328}# + #{body\ 1710}# + #{r\ 1672}# + #{w\ 1687}# + #{s\ 1688}# + 'c + '(load) + #{mod\ 1689}#) + (#{chi-void\ 1341}#))) + (if (let ((#{t\ 1714}# + (memq 'compile + #{when-list\ 1709}#))) + (if #{t\ 1714}# + #{t\ 1714}# + (if (eq? #{m\ 1674}# + 'c&e) + (memq 'eval + #{when-list\ 1709}#) + #f))) + (begin + (#{top-level-eval-hook\ 1258}# + (#{chi-top-sequence\ 1328}# + #{body\ 1710}# + #{r\ 1672}# + #{w\ 1687}# + #{s\ 1688}# + 'e + '(eval) + #{mod\ 1689}#) + #{mod\ 1689}#) + (#{chi-void\ 1341}#)) + (#{chi-void\ 1341}#)))))) + #{tmp\ 1704}#) + (syntax-violation + #f + "source expression failed to match any pattern" + #{tmp\ 1703}#))) + ($sc-dispatch + #{tmp\ 1703}# + '(any each-any any . each-any)))) + #{e\ 1686}#) + (if (memv #{type\ 1684}# + '(define-syntax-form)) + (let ((#{n\ 1715}# + (#{id-var-name\ 1319}# + #{value\ 1685}# + #{w\ 1687}#)) + (#{r\ 1716}# + (#{macros-only-env\ 1293}# #{r\ 1672}#))) + (if (memv #{m\ 1674}# (quote (c))) + (if (memq (quote compile) #{esew\ 1675}#) + (let ((#{e\ 1717}# + (#{chi-install-global\ 1329}# + #{n\ 1715}# + (#{chi\ 1333}# + #{e\ 1686}# + #{r\ 1716}# + #{w\ 1687}# + #{mod\ 1689}#)))) + (begin + (#{top-level-eval-hook\ 1258}# + #{e\ 1717}# + #{mod\ 1689}#) + (if (memq (quote load) #{esew\ 1675}#) + #{e\ 1717}# + (#{chi-void\ 1341}#)))) + (if (memq (quote load) #{esew\ 1675}#) + (#{chi-install-global\ 1329}# + #{n\ 1715}# + (#{chi\ 1333}# + #{e\ 1686}# + #{r\ 1716}# + #{w\ 1687}# + #{mod\ 1689}#)) + (#{chi-void\ 1341}#))) + (if (memv #{m\ 1674}# (quote (c&e))) + (let ((#{e\ 1718}# + (#{chi-install-global\ 1329}# + #{n\ 1715}# + (#{chi\ 1333}# + #{e\ 1686}# + #{r\ 1716}# + #{w\ 1687}# + #{mod\ 1689}#)))) + (begin + (#{top-level-eval-hook\ 1258}# + #{e\ 1718}# + #{mod\ 1689}#) + #{e\ 1718}#)) + (begin + (if (memq (quote eval) #{esew\ 1675}#) + (#{top-level-eval-hook\ 1258}# + (#{chi-install-global\ 1329}# + #{n\ 1715}# + (#{chi\ 1333}# + #{e\ 1686}# + #{r\ 1716}# + #{w\ 1687}# + #{mod\ 1689}#)) + #{mod\ 1689}#)) + (#{chi-void\ 1341}#))))) + (if (memv #{type\ 1684}# (quote (define-form))) + (let ((#{n\ 1719}# + (#{id-var-name\ 1319}# + #{value\ 1685}# + #{w\ 1687}#))) + (let ((#{type\ 1720}# + (#{binding-type\ 1289}# + (#{lookup\ 1294}# + #{n\ 1719}# + #{r\ 1672}# + #{mod\ 1689}#)))) + (if (memv #{type\ 1720}# + '(global core macro module-ref)) + (begin + (if (if (not (module-local-variable + (current-module) + #{n\ 1719}#)) + (current-module) + #f) + (let ((#{old\ 1721}# + (module-variable + (current-module) + #{n\ 1719}#))) + (module-define! + (current-module) + #{n\ 1719}# + (if (variable? #{old\ 1721}#) + (variable-ref #{old\ 1721}#) + #f)))) + (let ((#{x\ 1722}# + (#{build-global-definition\ 1272}# + #{s\ 1688}# + #{n\ 1719}# + (#{chi\ 1333}# + #{e\ 1686}# + #{r\ 1672}# + #{w\ 1687}# + #{mod\ 1689}#)))) + (begin + (if (eq? #{m\ 1674}# (quote c&e)) + (#{top-level-eval-hook\ 1258}# + #{x\ 1722}# + #{mod\ 1689}#)) + #{x\ 1722}#))) + (if (memv #{type\ 1720}# + '(displaced-lexical)) + (syntax-violation + #f + "identifier out of context" + #{e\ 1686}# + (#{wrap\ 1325}# + #{value\ 1685}# + #{w\ 1687}# + #{mod\ 1689}#)) + (syntax-violation + #f + "cannot define keyword at top level" + #{e\ 1686}# + (#{wrap\ 1325}# + #{value\ 1685}# + #{w\ 1687}# + #{mod\ 1689}#)))))) + (let ((#{x\ 1723}# + (#{chi-expr\ 1334}# + #{type\ 1684}# + #{value\ 1685}# + #{e\ 1686}# + #{r\ 1672}# + #{w\ 1687}# + #{s\ 1688}# + #{mod\ 1689}#))) + (begin + (if (eq? #{m\ 1674}# (quote c&e)) + (#{top-level-eval-hook\ 1258}# + #{x\ 1723}# + #{mod\ 1689}#)) + #{x\ 1723}#))))))))))) + (#{syntax-type\ 1331}# + (lambda (#{e\ 1724}# + #{r\ 1725}# + #{w\ 1726}# + #{s\ 1727}# + #{rib\ 1728}# + #{mod\ 1729}# + #{for-car?\ 1730}#) + (if (symbol? #{e\ 1724}#) + (let ((#{n\ 1731}# + (#{id-var-name\ 1319}# #{e\ 1724}# #{w\ 1726}#))) + (let ((#{b\ 1732}# + (#{lookup\ 1294}# + #{n\ 1731}# + #{r\ 1725}# + #{mod\ 1729}#))) + (let ((#{type\ 1733}# + (#{binding-type\ 1289}# #{b\ 1732}#))) + (if (memv #{type\ 1733}# (quote (lexical))) + (values + #{type\ 1733}# + (#{binding-value\ 1290}# #{b\ 1732}#) + #{e\ 1724}# + #{w\ 1726}# + #{s\ 1727}# + #{mod\ 1729}#) + (if (memv #{type\ 1733}# (quote (global))) + (values + #{type\ 1733}# + #{n\ 1731}# + #{e\ 1724}# + #{w\ 1726}# + #{s\ 1727}# + #{mod\ 1729}#) + (if (memv #{type\ 1733}# (quote (macro))) + (if #{for-car?\ 1730}# + (values + #{type\ 1733}# + (#{binding-value\ 1290}# #{b\ 1732}#) + #{e\ 1724}# + #{w\ 1726}# + #{s\ 1727}# + #{mod\ 1729}#) + (#{syntax-type\ 1331}# + (#{chi-macro\ 1336}# + (#{binding-value\ 1290}# #{b\ 1732}#) + #{e\ 1724}# + #{r\ 1725}# + #{w\ 1726}# + #{rib\ 1728}# + #{mod\ 1729}#) + #{r\ 1725}# + '(()) + #{s\ 1727}# + #{rib\ 1728}# + #{mod\ 1729}# + #f)) + (values + #{type\ 1733}# + (#{binding-value\ 1290}# #{b\ 1732}#) + #{e\ 1724}# + #{w\ 1726}# + #{s\ 1727}# + #{mod\ 1729}#))))))) + (if (pair? #{e\ 1724}#) + (let ((#{first\ 1734}# (car #{e\ 1724}#))) + (call-with-values + (lambda () + (#{syntax-type\ 1331}# + #{first\ 1734}# + #{r\ 1725}# + #{w\ 1726}# + #{s\ 1727}# + #{rib\ 1728}# + #{mod\ 1729}# + #t)) + (lambda (#{ftype\ 1735}# + #{fval\ 1736}# + #{fe\ 1737}# + #{fw\ 1738}# + #{fs\ 1739}# + #{fmod\ 1740}#) + (if (memv #{ftype\ 1735}# (quote (lexical))) + (values + 'lexical-call + #{fval\ 1736}# + #{e\ 1724}# + #{w\ 1726}# + #{s\ 1727}# + #{mod\ 1729}#) + (if (memv #{ftype\ 1735}# (quote (global))) + (values + 'global-call + (#{make-syntax-object\ 1280}# + #{fval\ 1736}# + #{w\ 1726}# + #{fmod\ 1740}#) + #{e\ 1724}# + #{w\ 1726}# + #{s\ 1727}# + #{mod\ 1729}#) + (if (memv #{ftype\ 1735}# (quote (macro))) + (#{syntax-type\ 1331}# + (#{chi-macro\ 1336}# + #{fval\ 1736}# + #{e\ 1724}# + #{r\ 1725}# + #{w\ 1726}# + #{rib\ 1728}# + #{mod\ 1729}#) + #{r\ 1725}# + '(()) + #{s\ 1727}# + #{rib\ 1728}# + #{mod\ 1729}# + #{for-car?\ 1730}#) + (if (memv #{ftype\ 1735}# (quote (module-ref))) + (call-with-values + (lambda () (#{fval\ 1736}# #{e\ 1724}#)) + (lambda (#{sym\ 1741}# #{mod\ 1742}#) + (#{syntax-type\ 1331}# + #{sym\ 1741}# + #{r\ 1725}# + #{w\ 1726}# + #{s\ 1727}# + #{rib\ 1728}# + #{mod\ 1742}# + #{for-car?\ 1730}#))) + (if (memv #{ftype\ 1735}# (quote (core))) + (values + 'core-form + #{fval\ 1736}# + #{e\ 1724}# + #{w\ 1726}# + #{s\ 1727}# + #{mod\ 1729}#) + (if (memv #{ftype\ 1735}# + '(local-syntax)) + (values + 'local-syntax-form + #{fval\ 1736}# + #{e\ 1724}# + #{w\ 1726}# + #{s\ 1727}# + #{mod\ 1729}#) + (if (memv #{ftype\ 1735}# (quote (begin))) + (values + 'begin-form + #f + #{e\ 1724}# + #{w\ 1726}# + #{s\ 1727}# + #{mod\ 1729}#) + (if (memv #{ftype\ 1735}# + '(eval-when)) + (values + 'eval-when-form + #f + #{e\ 1724}# + #{w\ 1726}# + #{s\ 1727}# + #{mod\ 1729}#) + (if (memv #{ftype\ 1735}# + '(define)) + ((lambda (#{tmp\ 1743}#) + ((lambda (#{tmp\ 1744}#) + (if (if #{tmp\ 1744}# + (apply (lambda (#{_\ 1745}# + #{name\ 1746}# + #{val\ 1747}#) + (#{id?\ 1297}# + #{name\ 1746}#)) + #{tmp\ 1744}#) + #f) + (apply (lambda (#{_\ 1748}# + #{name\ 1749}# + #{val\ 1750}#) + (values + 'define-form + #{name\ 1749}# + #{val\ 1750}# + #{w\ 1726}# + #{s\ 1727}# + #{mod\ 1729}#)) + #{tmp\ 1744}#) + ((lambda (#{tmp\ 1751}#) + (if (if #{tmp\ 1751}# + (apply (lambda (#{_\ 1752}# + #{name\ 1753}# + #{args\ 1754}# + #{e1\ 1755}# + #{e2\ 1756}#) + (if (#{id?\ 1297}# + #{name\ 1753}#) + (#{valid-bound-ids?\ 1322}# + (#{lambda-var-list\ 1345}# + #{args\ 1754}#)) + #f)) + #{tmp\ 1751}#) + #f) + (apply (lambda (#{_\ 1757}# + #{name\ 1758}# + #{args\ 1759}# + #{e1\ 1760}# + #{e2\ 1761}#) + (values + 'define-form + (#{wrap\ 1325}# + #{name\ 1758}# + #{w\ 1726}# + #{mod\ 1729}#) + (#{decorate-source\ 1262}# + (cons '#(syntax-object + lambda + ((top) + #(ribcage + #(_ + name + args + e1 + e2) + #((top) + (top) + (top) + (top) + (top)) + #("i" + "i" + "i" + "i" + "i")) + #(ribcage + () + () + ()) + #(ribcage + () + () + ()) + #(ribcage + #(ftype + fval + fe + fw + fs + fmod) + #((top) + (top) + (top) + (top) + (top) + (top)) + #("i" + "i" + "i" + "i" + "i" + "i")) + #(ribcage + () + () + ()) + #(ribcage + #(first) + #((top)) + #("i")) + #(ribcage + () + () + ()) + #(ribcage + () + () + ()) + #(ribcage + () + () + ()) + #(ribcage + #(e + r + w + s + rib + mod + for-car?) + #((top) + (top) + (top) + (top) + (top) + (top) + (top)) + #("i" + "i" + "i" + "i" + "i" + "i" + "i")) + #(ribcage + (lambda-var-list + gen-var + strip + ellipsis? + chi-void + eval-local-transformer + chi-local-syntax + chi-lambda-clause + chi-body + chi-macro + chi-application + chi-expr + chi + chi-top + syntax-type + chi-when-list + chi-install-global + chi-top-sequence + chi-sequence + source-wrap + wrap + bound-id-member? + distinct-bound-ids? + valid-bound-ids? + bound-id=? + free-id=? + id-var-name + same-marks? + join-marks + join-wraps + smart-append + make-binding-wrap + extend-ribcage! + make-empty-ribcage + new-mark + anti-mark + the-anti-mark + top-marked? + top-wrap + empty-wrap + set-ribcage-labels! + set-ribcage-marks! + set-ribcage-symnames! + ribcage-labels + ribcage-marks + ribcage-symnames + ribcage? + make-ribcage + gen-labels + gen-label + make-rename + rename-marks + rename-new + rename-old + subst-rename? + wrap-subst + wrap-marks + make-wrap + id-sym-name&marks + id-sym-name + id? + nonsymbol-id? + global-extend + lookup + macros-only-env + extend-var-env + extend-env + null-env + binding-value + binding-type + make-binding + arg-check + source-annotation + no-source + set-syntax-object-module! + set-syntax-object-wrap! + set-syntax-object-expression! + syntax-object-module + syntax-object-wrap + syntax-object-expression + syntax-object? + make-syntax-object + build-lexical-var + build-letrec + build-named-let + build-let + build-sequence + build-data + build-primref + build-lambda + build-global-definition + maybe-name-value! + build-global-assignment + build-global-reference + analyze-variable + build-lexical-assignment + build-lexical-reference + build-conditional + build-application + build-void + decorate-source + get-global-definition-hook + put-global-definition-hook + gensym-hook + local-eval-hook + top-level-eval-hook + fx< + fx= + fx- + fx+ + *mode* + noexpand) + ((top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top)) + ("i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i")) + #(ribcage + (define-structure + and-map*) + ((top) + (top)) + ("i" + "i"))) + (hygiene + guile)) + (#{wrap\ 1325}# + (cons #{args\ 1759}# + (cons #{e1\ 1760}# + #{e2\ 1761}#)) + #{w\ 1726}# + #{mod\ 1729}#)) + #{s\ 1727}#) + '(()) + #{s\ 1727}# + #{mod\ 1729}#)) + #{tmp\ 1751}#) + ((lambda (#{tmp\ 1763}#) + (if (if #{tmp\ 1763}# + (apply (lambda (#{_\ 1764}# + #{name\ 1765}#) + (#{id?\ 1297}# + #{name\ 1765}#)) + #{tmp\ 1763}#) + #f) + (apply (lambda (#{_\ 1766}# + #{name\ 1767}#) + (values + 'define-form + (#{wrap\ 1325}# + #{name\ 1767}# + #{w\ 1726}# + #{mod\ 1729}#) + '(#(syntax-object + if + ((top) + #(ribcage + #(_ + name) + #((top) + (top)) + #("i" + "i")) + #(ribcage + () + () + ()) + #(ribcage + () + () + ()) + #(ribcage + #(ftype + fval + fe + fw + fs + fmod) + #((top) + (top) + (top) + (top) + (top) + (top)) + #("i" + "i" + "i" + "i" + "i" + "i")) + #(ribcage + () + () + ()) + #(ribcage + #(first) + #((top)) + #("i")) + #(ribcage + () + () + ()) + #(ribcage + () + () + ()) + #(ribcage + () + () + ()) + #(ribcage + #(e + r + w + s + rib + mod + for-car?) + #((top) + (top) + (top) + (top) + (top) + (top) + (top)) + #("i" + "i" + "i" + "i" + "i" + "i" + "i")) + #(ribcage + (lambda-var-list + gen-var + strip + ellipsis? + chi-void + eval-local-transformer + chi-local-syntax + chi-lambda-clause + chi-body + chi-macro + chi-application + chi-expr + chi + chi-top + syntax-type + chi-when-list + chi-install-global + chi-top-sequence + chi-sequence + source-wrap + wrap + bound-id-member? + distinct-bound-ids? + valid-bound-ids? + bound-id=? + free-id=? + id-var-name + same-marks? + join-marks + join-wraps + smart-append + make-binding-wrap + extend-ribcage! + make-empty-ribcage + new-mark + anti-mark + the-anti-mark + top-marked? + top-wrap + empty-wrap + set-ribcage-labels! + set-ribcage-marks! + set-ribcage-symnames! + ribcage-labels + ribcage-marks + ribcage-symnames + ribcage? + make-ribcage + gen-labels + gen-label + make-rename + rename-marks + rename-new + rename-old + subst-rename? + wrap-subst + wrap-marks + make-wrap + id-sym-name&marks + id-sym-name + id? + nonsymbol-id? + global-extend + lookup + macros-only-env + extend-var-env + extend-env + null-env + binding-value + binding-type + make-binding + arg-check + source-annotation + no-source + set-syntax-object-module! + set-syntax-object-wrap! + set-syntax-object-expression! + syntax-object-module + syntax-object-wrap + syntax-object-expression + syntax-object? + make-syntax-object + build-lexical-var + build-letrec + build-named-let + build-let + build-sequence + build-data + build-primref + build-lambda + build-global-definition + maybe-name-value! + build-global-assignment + build-global-reference + analyze-variable + build-lexical-assignment + build-lexical-reference + build-conditional + build-application + build-void + decorate-source + get-global-definition-hook + put-global-definition-hook + gensym-hook + local-eval-hook + top-level-eval-hook + fx< + fx= + fx- + fx+ + *mode* + noexpand) + ((top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top)) + ("i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i")) + #(ribcage + (define-structure + and-map*) + ((top) + (top)) + ("i" + "i"))) + (hygiene + guile)) + #(syntax-object + #f + ((top) + #(ribcage + #(_ + name) + #((top) + (top)) + #("i" + "i")) + #(ribcage + () + () + ()) + #(ribcage + () + () + ()) + #(ribcage + #(ftype + fval + fe + fw + fs + fmod) + #((top) + (top) + (top) + (top) + (top) + (top)) + #("i" + "i" + "i" + "i" + "i" + "i")) + #(ribcage + () + () + ()) + #(ribcage + #(first) + #((top)) + #("i")) + #(ribcage + () + () + ()) + #(ribcage + () + () + ()) + #(ribcage + () + () + ()) + #(ribcage + #(e + r + w + s + rib + mod + for-car?) + #((top) + (top) + (top) + (top) + (top) + (top) + (top)) + #("i" + "i" + "i" + "i" + "i" + "i" + "i")) + #(ribcage + (lambda-var-list + gen-var + strip + ellipsis? + chi-void + eval-local-transformer + chi-local-syntax + chi-lambda-clause + chi-body + chi-macro + chi-application + chi-expr + chi + chi-top + syntax-type + chi-when-list + chi-install-global + chi-top-sequence + chi-sequence + source-wrap + wrap + bound-id-member? + distinct-bound-ids? + valid-bound-ids? + bound-id=? + free-id=? + id-var-name + same-marks? + join-marks + join-wraps + smart-append + make-binding-wrap + extend-ribcage! + make-empty-ribcage + new-mark + anti-mark + the-anti-mark + top-marked? + top-wrap + empty-wrap + set-ribcage-labels! + set-ribcage-marks! + set-ribcage-symnames! + ribcage-labels + ribcage-marks + ribcage-symnames + ribcage? + make-ribcage + gen-labels + gen-label + make-rename + rename-marks + rename-new + rename-old + subst-rename? + wrap-subst + wrap-marks + make-wrap + id-sym-name&marks + id-sym-name + id? + nonsymbol-id? + global-extend + lookup + macros-only-env + extend-var-env + extend-env + null-env + binding-value + binding-type + make-binding + arg-check + source-annotation + no-source + set-syntax-object-module! + set-syntax-object-wrap! + set-syntax-object-expression! + syntax-object-module + syntax-object-wrap + syntax-object-expression + syntax-object? + make-syntax-object + build-lexical-var + build-letrec + build-named-let + build-let + build-sequence + build-data + build-primref + build-lambda + build-global-definition + maybe-name-value! + build-global-assignment + build-global-reference + analyze-variable + build-lexical-assignment + build-lexical-reference + build-conditional + build-application + build-void + decorate-source + get-global-definition-hook + put-global-definition-hook + gensym-hook + local-eval-hook + top-level-eval-hook + fx< + fx= + fx- + fx+ + *mode* + noexpand) + ((top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top)) + ("i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i")) + #(ribcage + (define-structure + and-map*) + ((top) + (top)) + ("i" + "i"))) + (hygiene + guile)) + #(syntax-object + #f + ((top) + #(ribcage + #(_ + name) + #((top) + (top)) + #("i" + "i")) + #(ribcage + () + () + ()) + #(ribcage + () + () + ()) + #(ribcage + #(ftype + fval + fe + fw + fs + fmod) + #((top) + (top) + (top) + (top) + (top) + (top)) + #("i" + "i" + "i" + "i" + "i" + "i")) + #(ribcage + () + () + ()) + #(ribcage + #(first) + #((top)) + #("i")) + #(ribcage + () + () + ()) + #(ribcage + () + () + ()) + #(ribcage + () + () + ()) + #(ribcage + #(e + r + w + s + rib + mod + for-car?) + #((top) + (top) + (top) + (top) + (top) + (top) + (top)) + #("i" + "i" + "i" + "i" + "i" + "i" + "i")) + #(ribcage + (lambda-var-list + gen-var + strip + ellipsis? + chi-void + eval-local-transformer + chi-local-syntax + chi-lambda-clause + chi-body + chi-macro + chi-application + chi-expr + chi + chi-top + syntax-type + chi-when-list + chi-install-global + chi-top-sequence + chi-sequence + source-wrap + wrap + bound-id-member? + distinct-bound-ids? + valid-bound-ids? + bound-id=? + free-id=? + id-var-name + same-marks? + join-marks + join-wraps + smart-append + make-binding-wrap + extend-ribcage! + make-empty-ribcage + new-mark + anti-mark + the-anti-mark + top-marked? + top-wrap + empty-wrap + set-ribcage-labels! + set-ribcage-marks! + set-ribcage-symnames! + ribcage-labels + ribcage-marks + ribcage-symnames + ribcage? + make-ribcage + gen-labels + gen-label + make-rename + rename-marks + rename-new + rename-old + subst-rename? + wrap-subst + wrap-marks + make-wrap + id-sym-name&marks + id-sym-name + id? + nonsymbol-id? + global-extend + lookup + macros-only-env + extend-var-env + extend-env + null-env + binding-value + binding-type + make-binding + arg-check + source-annotation + no-source + set-syntax-object-module! + set-syntax-object-wrap! + set-syntax-object-expression! + syntax-object-module + syntax-object-wrap + syntax-object-expression + syntax-object? + make-syntax-object + build-lexical-var + build-letrec + build-named-let + build-let + build-sequence + build-data + build-primref + build-lambda + build-global-definition + maybe-name-value! + build-global-assignment + build-global-reference + analyze-variable + build-lexical-assignment + build-lexical-reference + build-conditional + build-application + build-void + decorate-source + get-global-definition-hook + put-global-definition-hook + gensym-hook + local-eval-hook + top-level-eval-hook + fx< + fx= + fx- + fx+ + *mode* + noexpand) + ((top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top)) + ("i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i")) + #(ribcage + (define-structure + and-map*) + ((top) + (top)) + ("i" + "i"))) + (hygiene + guile))) + '(()) + #{s\ 1727}# + #{mod\ 1729}#)) + #{tmp\ 1763}#) + (syntax-violation + #f + "source expression failed to match any pattern" + #{tmp\ 1743}#))) + ($sc-dispatch + #{tmp\ 1743}# + '(any any))))) + ($sc-dispatch + #{tmp\ 1743}# + '(any (any . any) + any + . + each-any))))) + ($sc-dispatch + #{tmp\ 1743}# + '(any any any)))) + #{e\ 1724}#) + (if (memv #{ftype\ 1735}# + '(define-syntax)) + ((lambda (#{tmp\ 1768}#) + ((lambda (#{tmp\ 1769}#) + (if (if #{tmp\ 1769}# + (apply (lambda (#{_\ 1770}# + #{name\ 1771}# + #{val\ 1772}#) + (#{id?\ 1297}# + #{name\ 1771}#)) + #{tmp\ 1769}#) + #f) + (apply (lambda (#{_\ 1773}# + #{name\ 1774}# + #{val\ 1775}#) + (values + 'define-syntax-form + #{name\ 1774}# + #{val\ 1775}# + #{w\ 1726}# + #{s\ 1727}# + #{mod\ 1729}#)) + #{tmp\ 1769}#) + (syntax-violation + #f + "source expression failed to match any pattern" + #{tmp\ 1768}#))) + ($sc-dispatch + #{tmp\ 1768}# + '(any any any)))) + #{e\ 1724}#) + (values + 'call + #f + #{e\ 1724}# + #{w\ 1726}# + #{s\ 1727}# + #{mod\ 1729}#)))))))))))))) + (if (#{syntax-object?\ 1281}# #{e\ 1724}#) + (#{syntax-type\ 1331}# + (#{syntax-object-expression\ 1282}# #{e\ 1724}#) + #{r\ 1725}# + (#{join-wraps\ 1316}# + #{w\ 1726}# + (#{syntax-object-wrap\ 1283}# #{e\ 1724}#)) + #{s\ 1727}# + #{rib\ 1728}# + (let ((#{t\ 1776}# + (#{syntax-object-module\ 1284}# #{e\ 1724}#))) + (if #{t\ 1776}# #{t\ 1776}# #{mod\ 1729}#)) + #{for-car?\ 1730}#) + (if (self-evaluating? #{e\ 1724}#) + (values + 'constant + #f + #{e\ 1724}# + #{w\ 1726}# + #{s\ 1727}# + #{mod\ 1729}#) + (values + 'other + #f + #{e\ 1724}# + #{w\ 1726}# + #{s\ 1727}# + #{mod\ 1729}#))))))) + (#{chi-when-list\ 1330}# + (lambda (#{e\ 1777}# #{when-list\ 1778}# #{w\ 1779}#) + (letrec ((#{f\ 1780}# + (lambda (#{when-list\ 1781}# #{situations\ 1782}#) + (if (null? #{when-list\ 1781}#) + #{situations\ 1782}# + (#{f\ 1780}# + (cdr #{when-list\ 1781}#) + (cons (let ((#{x\ 1783}# + (car #{when-list\ 1781}#))) + (if (#{free-id=?\ 1320}# + #{x\ 1783}# + '#(syntax-object + compile + ((top) + #(ribcage () () ()) + #(ribcage () () ()) + #(ribcage () () ()) + #(ribcage + #(x) + #((top)) + #("i")) + #(ribcage () () ()) + #(ribcage + #(f when-list situations) + #((top) (top) (top)) + #("i" "i" "i")) + #(ribcage () () ()) + #(ribcage + #(e when-list w) + #((top) (top) (top)) + #("i" "i" "i")) + #(ribcage + (lambda-var-list + gen-var + strip + ellipsis? + chi-void + eval-local-transformer + chi-local-syntax + chi-lambda-clause + chi-body + chi-macro + chi-application + chi-expr + chi + chi-top + syntax-type + chi-when-list + chi-install-global + chi-top-sequence + chi-sequence + source-wrap + wrap + bound-id-member? + distinct-bound-ids? + valid-bound-ids? + bound-id=? + free-id=? + id-var-name + same-marks? + join-marks + join-wraps + smart-append + make-binding-wrap + extend-ribcage! + make-empty-ribcage + new-mark + anti-mark + the-anti-mark + top-marked? + top-wrap + empty-wrap + set-ribcage-labels! + set-ribcage-marks! + set-ribcage-symnames! + ribcage-labels + ribcage-marks + ribcage-symnames + ribcage? + make-ribcage + gen-labels + gen-label + make-rename + rename-marks + rename-new + rename-old + subst-rename? + wrap-subst + wrap-marks + make-wrap + id-sym-name&marks + id-sym-name + id? + nonsymbol-id? + global-extend + lookup + macros-only-env + extend-var-env + extend-env + null-env + binding-value + binding-type + make-binding + arg-check + source-annotation + no-source + set-syntax-object-module! + set-syntax-object-wrap! + set-syntax-object-expression! + syntax-object-module + syntax-object-wrap + syntax-object-expression + syntax-object? + make-syntax-object + build-lexical-var + build-letrec + build-named-let + build-let + build-sequence + build-data + build-primref + build-lambda + build-global-definition + maybe-name-value! + build-global-assignment + build-global-reference + analyze-variable + build-lexical-assignment + build-lexical-reference + build-conditional + build-application + build-void + decorate-source + get-global-definition-hook + put-global-definition-hook + gensym-hook + local-eval-hook + top-level-eval-hook + fx< + fx= + fx- + fx+ + *mode* + noexpand) + ((top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top)) + ("i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i")) + #(ribcage + (define-structure and-map*) + ((top) (top)) + ("i" "i"))) + (hygiene guile))) + 'compile + (if (#{free-id=?\ 1320}# + #{x\ 1783}# + '#(syntax-object + load + ((top) + #(ribcage () () ()) + #(ribcage () () ()) + #(ribcage () () ()) + #(ribcage + #(x) + #((top)) + #("i")) + #(ribcage () () ()) + #(ribcage + #(f when-list situations) + #((top) (top) (top)) + #("i" "i" "i")) + #(ribcage () () ()) + #(ribcage + #(e when-list w) + #((top) (top) (top)) + #("i" "i" "i")) + #(ribcage + (lambda-var-list + gen-var + strip + ellipsis? + chi-void + eval-local-transformer + chi-local-syntax + chi-lambda-clause + chi-body + chi-macro + chi-application + chi-expr + chi + chi-top + syntax-type + chi-when-list + chi-install-global + chi-top-sequence + chi-sequence + source-wrap + wrap + bound-id-member? + distinct-bound-ids? + valid-bound-ids? + bound-id=? + free-id=? + id-var-name + same-marks? + join-marks + join-wraps + smart-append + make-binding-wrap + extend-ribcage! + make-empty-ribcage + new-mark + anti-mark + the-anti-mark + top-marked? + top-wrap + empty-wrap + set-ribcage-labels! + set-ribcage-marks! + set-ribcage-symnames! + ribcage-labels + ribcage-marks + ribcage-symnames + ribcage? + make-ribcage + gen-labels + gen-label + make-rename + rename-marks + rename-new + rename-old + subst-rename? + wrap-subst + wrap-marks + make-wrap + id-sym-name&marks + id-sym-name + id? + nonsymbol-id? + global-extend + lookup + macros-only-env + extend-var-env + extend-env + null-env + binding-value + binding-type + make-binding + arg-check + source-annotation + no-source + set-syntax-object-module! + set-syntax-object-wrap! + set-syntax-object-expression! + syntax-object-module + syntax-object-wrap + syntax-object-expression + syntax-object? + make-syntax-object + build-lexical-var + build-letrec + build-named-let + build-let + build-sequence + build-data + build-primref + build-lambda + build-global-definition + maybe-name-value! + build-global-assignment + build-global-reference + analyze-variable + build-lexical-assignment + build-lexical-reference + build-conditional + build-application + build-void + decorate-source + get-global-definition-hook + put-global-definition-hook + gensym-hook + local-eval-hook + top-level-eval-hook + fx< + fx= + fx- + fx+ + *mode* + noexpand) + ((top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top)) + ("i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i")) + #(ribcage + (define-structure + and-map*) + ((top) (top)) + ("i" "i"))) + (hygiene guile))) + 'load + (if (#{free-id=?\ 1320}# + #{x\ 1783}# + '#(syntax-object + eval + ((top) + #(ribcage () () ()) + #(ribcage () () ()) + #(ribcage () () ()) + #(ribcage + #(x) + #((top)) + #("i")) + #(ribcage () () ()) + #(ribcage + #(f + when-list + situations) + #((top) (top) (top)) + #("i" "i" "i")) + #(ribcage () () ()) + #(ribcage + #(e when-list w) + #((top) (top) (top)) + #("i" "i" "i")) + #(ribcage + (lambda-var-list + gen-var + strip + ellipsis? + chi-void + eval-local-transformer + chi-local-syntax + chi-lambda-clause + chi-body + chi-macro + chi-application + chi-expr + chi + chi-top + syntax-type + chi-when-list + chi-install-global + chi-top-sequence + chi-sequence + source-wrap + wrap + bound-id-member? + distinct-bound-ids? + valid-bound-ids? + bound-id=? + free-id=? + id-var-name + same-marks? + join-marks + join-wraps + smart-append + make-binding-wrap + extend-ribcage! + make-empty-ribcage + new-mark + anti-mark + the-anti-mark + top-marked? + top-wrap + empty-wrap + set-ribcage-labels! + set-ribcage-marks! + set-ribcage-symnames! + ribcage-labels + ribcage-marks + ribcage-symnames + ribcage? + make-ribcage + gen-labels + gen-label + make-rename + rename-marks + rename-new + rename-old + subst-rename? + wrap-subst + wrap-marks + make-wrap + id-sym-name&marks + id-sym-name + id? + nonsymbol-id? + global-extend + lookup + macros-only-env + extend-var-env + extend-env + null-env + binding-value + binding-type + make-binding + arg-check + source-annotation + no-source + set-syntax-object-module! + set-syntax-object-wrap! + set-syntax-object-expression! + syntax-object-module + syntax-object-wrap + syntax-object-expression + syntax-object? + make-syntax-object + build-lexical-var + build-letrec + build-named-let + build-let + build-sequence + build-data + build-primref + build-lambda + build-global-definition + maybe-name-value! + build-global-assignment + build-global-reference + analyze-variable + build-lexical-assignment + build-lexical-reference + build-conditional + build-application + build-void + decorate-source + get-global-definition-hook + put-global-definition-hook + gensym-hook + local-eval-hook + top-level-eval-hook + fx< + fx= + fx- + fx+ + *mode* + noexpand) + ((top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top)) + ("i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i")) + #(ribcage + (define-structure + and-map*) + ((top) (top)) + ("i" "i"))) + (hygiene guile))) + 'eval + (syntax-violation + 'eval-when + "invalid situation" + #{e\ 1777}# + (#{wrap\ 1325}# + #{x\ 1783}# + #{w\ 1779}# + #f)))))) + #{situations\ 1782}#)))))) + (#{f\ 1780}# #{when-list\ 1778}# (quote ()))))) + (#{chi-install-global\ 1329}# + (lambda (#{name\ 1784}# #{e\ 1785}#) + (#{build-global-definition\ 1272}# + #f + #{name\ 1784}# + (if (let ((#{v\ 1786}# + (module-variable + (current-module) + #{name\ 1784}#))) + (if #{v\ 1786}# + (if (variable-bound? #{v\ 1786}#) + (if (macro? (variable-ref #{v\ 1786}#)) + (not (eq? (macro-type (variable-ref #{v\ 1786}#)) + 'syncase-macro)) + #f) + #f) + #f)) + (#{build-application\ 1264}# + #f + (#{build-primref\ 1274}# + #f + 'make-extended-syncase-macro) + (list (#{build-application\ 1264}# + #f + (#{build-primref\ 1274}# #f (quote module-ref)) + (list (#{build-application\ 1264}# + #f + (#{build-primref\ 1274}# + #f + 'current-module) + '()) + (#{build-data\ 1275}# #f #{name\ 1784}#))) + (#{build-data\ 1275}# #f (quote macro)) + #{e\ 1785}#)) + (#{build-application\ 1264}# + #f + (#{build-primref\ 1274}# + #f + 'make-syncase-macro) + (list (#{build-data\ 1275}# #f (quote macro)) + #{e\ 1785}#)))))) + (#{chi-top-sequence\ 1328}# + (lambda (#{body\ 1787}# + #{r\ 1788}# + #{w\ 1789}# + #{s\ 1790}# + #{m\ 1791}# + #{esew\ 1792}# + #{mod\ 1793}#) + (#{build-sequence\ 1276}# + #{s\ 1790}# + (letrec ((#{dobody\ 1794}# + (lambda (#{body\ 1795}# + #{r\ 1796}# + #{w\ 1797}# + #{m\ 1798}# + #{esew\ 1799}# + #{mod\ 1800}#) + (if (null? #{body\ 1795}#) + '() + (let ((#{first\ 1801}# + (#{chi-top\ 1332}# + (car #{body\ 1795}#) + #{r\ 1796}# + #{w\ 1797}# + #{m\ 1798}# + #{esew\ 1799}# + #{mod\ 1800}#))) + (cons #{first\ 1801}# + (#{dobody\ 1794}# + (cdr #{body\ 1795}#) + #{r\ 1796}# + #{w\ 1797}# + #{m\ 1798}# + #{esew\ 1799}# + #{mod\ 1800}#))))))) + (#{dobody\ 1794}# + #{body\ 1787}# + #{r\ 1788}# + #{w\ 1789}# + #{m\ 1791}# + #{esew\ 1792}# + #{mod\ 1793}#))))) + (#{chi-sequence\ 1327}# + (lambda (#{body\ 1802}# + #{r\ 1803}# + #{w\ 1804}# + #{s\ 1805}# + #{mod\ 1806}#) + (#{build-sequence\ 1276}# + #{s\ 1805}# + (letrec ((#{dobody\ 1807}# + (lambda (#{body\ 1808}# + #{r\ 1809}# + #{w\ 1810}# + #{mod\ 1811}#) + (if (null? #{body\ 1808}#) + '() + (let ((#{first\ 1812}# + (#{chi\ 1333}# + (car #{body\ 1808}#) + #{r\ 1809}# + #{w\ 1810}# + #{mod\ 1811}#))) + (cons #{first\ 1812}# + (#{dobody\ 1807}# + (cdr #{body\ 1808}#) + #{r\ 1809}# + #{w\ 1810}# + #{mod\ 1811}#))))))) + (#{dobody\ 1807}# + #{body\ 1802}# + #{r\ 1803}# + #{w\ 1804}# + #{mod\ 1806}#))))) + (#{source-wrap\ 1326}# + (lambda (#{x\ 1813}# + #{w\ 1814}# + #{s\ 1815}# + #{defmod\ 1816}#) + (#{wrap\ 1325}# + (#{decorate-source\ 1262}# + #{x\ 1813}# + #{s\ 1815}#) + #{w\ 1814}# + #{defmod\ 1816}#))) + (#{wrap\ 1325}# + (lambda (#{x\ 1817}# #{w\ 1818}# #{defmod\ 1819}#) + (if (if (null? (#{wrap-marks\ 1300}# #{w\ 1818}#)) + (null? (#{wrap-subst\ 1301}# #{w\ 1818}#)) + #f) + #{x\ 1817}# + (if (#{syntax-object?\ 1281}# #{x\ 1817}#) + (#{make-syntax-object\ 1280}# + (#{syntax-object-expression\ 1282}# #{x\ 1817}#) + (#{join-wraps\ 1316}# + #{w\ 1818}# + (#{syntax-object-wrap\ 1283}# #{x\ 1817}#)) + (#{syntax-object-module\ 1284}# #{x\ 1817}#)) + (if (null? #{x\ 1817}#) + #{x\ 1817}# + (#{make-syntax-object\ 1280}# + #{x\ 1817}# + #{w\ 1818}# + #{defmod\ 1819}#)))))) + (#{bound-id-member?\ 1324}# + (lambda (#{x\ 1820}# #{list\ 1821}#) + (if (not (null? #{list\ 1821}#)) + (let ((#{t\ 1822}# + (#{bound-id=?\ 1321}# + #{x\ 1820}# + (car #{list\ 1821}#)))) + (if #{t\ 1822}# + #{t\ 1822}# + (#{bound-id-member?\ 1324}# + #{x\ 1820}# + (cdr #{list\ 1821}#)))) + #f))) + (#{distinct-bound-ids?\ 1323}# + (lambda (#{ids\ 1823}#) + (letrec ((#{distinct?\ 1824}# + (lambda (#{ids\ 1825}#) + (let ((#{t\ 1826}# (null? #{ids\ 1825}#))) + (if #{t\ 1826}# + #{t\ 1826}# + (if (not (#{bound-id-member?\ 1324}# + (car #{ids\ 1825}#) + (cdr #{ids\ 1825}#))) + (#{distinct?\ 1824}# (cdr #{ids\ 1825}#)) + #f)))))) + (#{distinct?\ 1824}# #{ids\ 1823}#)))) + (#{valid-bound-ids?\ 1322}# + (lambda (#{ids\ 1827}#) + (if (letrec ((#{all-ids?\ 1828}# + (lambda (#{ids\ 1829}#) + (let ((#{t\ 1830}# (null? #{ids\ 1829}#))) + (if #{t\ 1830}# + #{t\ 1830}# + (if (#{id?\ 1297}# (car #{ids\ 1829}#)) + (#{all-ids?\ 1828}# (cdr #{ids\ 1829}#)) + #f)))))) + (#{all-ids?\ 1828}# #{ids\ 1827}#)) + (#{distinct-bound-ids?\ 1323}# #{ids\ 1827}#) + #f))) + (#{bound-id=?\ 1321}# + (lambda (#{i\ 1831}# #{j\ 1832}#) + (if (if (#{syntax-object?\ 1281}# #{i\ 1831}#) + (#{syntax-object?\ 1281}# #{j\ 1832}#) + #f) + (if (eq? (#{syntax-object-expression\ 1282}# #{i\ 1831}#) + (#{syntax-object-expression\ 1282}# #{j\ 1832}#)) + (#{same-marks?\ 1318}# + (#{wrap-marks\ 1300}# + (#{syntax-object-wrap\ 1283}# #{i\ 1831}#)) + (#{wrap-marks\ 1300}# + (#{syntax-object-wrap\ 1283}# #{j\ 1832}#))) + #f) + (eq? #{i\ 1831}# #{j\ 1832}#)))) + (#{free-id=?\ 1320}# + (lambda (#{i\ 1833}# #{j\ 1834}#) + (if (eq? (let ((#{x\ 1835}# #{i\ 1833}#)) + (if (#{syntax-object?\ 1281}# #{x\ 1835}#) + (#{syntax-object-expression\ 1282}# #{x\ 1835}#) + #{x\ 1835}#)) + (let ((#{x\ 1836}# #{j\ 1834}#)) + (if (#{syntax-object?\ 1281}# #{x\ 1836}#) + (#{syntax-object-expression\ 1282}# #{x\ 1836}#) + #{x\ 1836}#))) + (eq? (#{id-var-name\ 1319}# #{i\ 1833}# (quote (()))) + (#{id-var-name\ 1319}# #{j\ 1834}# (quote (())))) + #f))) + (#{id-var-name\ 1319}# + (lambda (#{id\ 1837}# #{w\ 1838}#) + (letrec ((#{search-vector-rib\ 1841}# + (lambda (#{sym\ 1847}# + #{subst\ 1848}# + #{marks\ 1849}# + #{symnames\ 1850}# + #{ribcage\ 1851}#) + (let ((#{n\ 1852}# + (vector-length #{symnames\ 1850}#))) + (letrec ((#{f\ 1853}# + (lambda (#{i\ 1854}#) + (if (#{fx=\ 1256}# + #{i\ 1854}# + #{n\ 1852}#) + (#{search\ 1839}# + #{sym\ 1847}# + (cdr #{subst\ 1848}#) + #{marks\ 1849}#) + (if (if (eq? (vector-ref + #{symnames\ 1850}# + #{i\ 1854}#) + #{sym\ 1847}#) + (#{same-marks?\ 1318}# + #{marks\ 1849}# + (vector-ref + (#{ribcage-marks\ 1307}# + #{ribcage\ 1851}#) + #{i\ 1854}#)) + #f) + (values + (vector-ref + (#{ribcage-labels\ 1308}# + #{ribcage\ 1851}#) + #{i\ 1854}#) + #{marks\ 1849}#) + (#{f\ 1853}# + (#{fx+\ 1254}# + #{i\ 1854}# + 1))))))) + (#{f\ 1853}# 0))))) + (#{search-list-rib\ 1840}# + (lambda (#{sym\ 1855}# + #{subst\ 1856}# + #{marks\ 1857}# + #{symnames\ 1858}# + #{ribcage\ 1859}#) + (letrec ((#{f\ 1860}# + (lambda (#{symnames\ 1861}# #{i\ 1862}#) + (if (null? #{symnames\ 1861}#) + (#{search\ 1839}# + #{sym\ 1855}# + (cdr #{subst\ 1856}#) + #{marks\ 1857}#) + (if (if (eq? (car #{symnames\ 1861}#) + #{sym\ 1855}#) + (#{same-marks?\ 1318}# + #{marks\ 1857}# + (list-ref + (#{ribcage-marks\ 1307}# + #{ribcage\ 1859}#) + #{i\ 1862}#)) + #f) + (values + (list-ref + (#{ribcage-labels\ 1308}# + #{ribcage\ 1859}#) + #{i\ 1862}#) + #{marks\ 1857}#) + (#{f\ 1860}# + (cdr #{symnames\ 1861}#) + (#{fx+\ 1254}# + #{i\ 1862}# + 1))))))) + (#{f\ 1860}# #{symnames\ 1858}# 0)))) + (#{search\ 1839}# + (lambda (#{sym\ 1863}# + #{subst\ 1864}# + #{marks\ 1865}#) + (if (null? #{subst\ 1864}#) + (values #f #{marks\ 1865}#) + (let ((#{fst\ 1866}# (car #{subst\ 1864}#))) + (if (eq? #{fst\ 1866}# (quote shift)) + (#{search\ 1839}# + #{sym\ 1863}# + (cdr #{subst\ 1864}#) + (cdr #{marks\ 1865}#)) + (let ((#{symnames\ 1867}# + (#{ribcage-symnames\ 1306}# + #{fst\ 1866}#))) + (if (vector? #{symnames\ 1867}#) + (#{search-vector-rib\ 1841}# + #{sym\ 1863}# + #{subst\ 1864}# + #{marks\ 1865}# + #{symnames\ 1867}# + #{fst\ 1866}#) + (#{search-list-rib\ 1840}# + #{sym\ 1863}# + #{subst\ 1864}# + #{marks\ 1865}# + #{symnames\ 1867}# + #{fst\ 1866}#))))))))) + (if (symbol? #{id\ 1837}#) + (let ((#{t\ 1868}# + (call-with-values + (lambda () + (#{search\ 1839}# + #{id\ 1837}# + (#{wrap-subst\ 1301}# #{w\ 1838}#) + (#{wrap-marks\ 1300}# #{w\ 1838}#))) + (lambda (#{x\ 1870}# . #{ignore\ 1869}#) + #{x\ 1870}#)))) + (if #{t\ 1868}# #{t\ 1868}# #{id\ 1837}#)) + (if (#{syntax-object?\ 1281}# #{id\ 1837}#) + (let ((#{id\ 1871}# + (#{syntax-object-expression\ 1282}# #{id\ 1837}#)) + (#{w1\ 1872}# + (#{syntax-object-wrap\ 1283}# #{id\ 1837}#))) + (let ((#{marks\ 1873}# + (#{join-marks\ 1317}# + (#{wrap-marks\ 1300}# #{w\ 1838}#) + (#{wrap-marks\ 1300}# #{w1\ 1872}#)))) + (call-with-values + (lambda () + (#{search\ 1839}# + #{id\ 1871}# + (#{wrap-subst\ 1301}# #{w\ 1838}#) + #{marks\ 1873}#)) + (lambda (#{new-id\ 1874}# #{marks\ 1875}#) + (let ((#{t\ 1876}# #{new-id\ 1874}#)) + (if #{t\ 1876}# + #{t\ 1876}# + (let ((#{t\ 1877}# + (call-with-values + (lambda () + (#{search\ 1839}# + #{id\ 1871}# + (#{wrap-subst\ 1301}# + #{w1\ 1872}#) + #{marks\ 1875}#)) + (lambda (#{x\ 1879}# + . + #{ignore\ 1878}#) + #{x\ 1879}#)))) + (if #{t\ 1877}# + #{t\ 1877}# + #{id\ 1871}#)))))))) + (syntax-violation + 'id-var-name + "invalid id" + #{id\ 1837}#)))))) + (#{same-marks?\ 1318}# + (lambda (#{x\ 1880}# #{y\ 1881}#) + (let ((#{t\ 1882}# (eq? #{x\ 1880}# #{y\ 1881}#))) + (if #{t\ 1882}# + #{t\ 1882}# + (if (not (null? #{x\ 1880}#)) + (if (not (null? #{y\ 1881}#)) + (if (eq? (car #{x\ 1880}#) (car #{y\ 1881}#)) + (#{same-marks?\ 1318}# + (cdr #{x\ 1880}#) + (cdr #{y\ 1881}#)) + #f) + #f) + #f))))) + (#{join-marks\ 1317}# + (lambda (#{m1\ 1883}# #{m2\ 1884}#) + (#{smart-append\ 1315}# + #{m1\ 1883}# + #{m2\ 1884}#))) + (#{join-wraps\ 1316}# + (lambda (#{w1\ 1885}# #{w2\ 1886}#) + (let ((#{m1\ 1887}# + (#{wrap-marks\ 1300}# #{w1\ 1885}#)) + (#{s1\ 1888}# + (#{wrap-subst\ 1301}# #{w1\ 1885}#))) + (if (null? #{m1\ 1887}#) + (if (null? #{s1\ 1888}#) + #{w2\ 1886}# + (#{make-wrap\ 1299}# + (#{wrap-marks\ 1300}# #{w2\ 1886}#) + (#{smart-append\ 1315}# + #{s1\ 1888}# + (#{wrap-subst\ 1301}# #{w2\ 1886}#)))) + (#{make-wrap\ 1299}# + (#{smart-append\ 1315}# + #{m1\ 1887}# + (#{wrap-marks\ 1300}# #{w2\ 1886}#)) + (#{smart-append\ 1315}# + #{s1\ 1888}# + (#{wrap-subst\ 1301}# #{w2\ 1886}#))))))) + (#{smart-append\ 1315}# + (lambda (#{m1\ 1889}# #{m2\ 1890}#) + (if (null? #{m2\ 1890}#) + #{m1\ 1889}# + (append #{m1\ 1889}# #{m2\ 1890}#)))) + (#{make-binding-wrap\ 1314}# + (lambda (#{ids\ 1891}# #{labels\ 1892}# #{w\ 1893}#) + (if (null? #{ids\ 1891}#) + #{w\ 1893}# + (#{make-wrap\ 1299}# + (#{wrap-marks\ 1300}# #{w\ 1893}#) + (cons (let ((#{labelvec\ 1894}# + (list->vector #{labels\ 1892}#))) + (let ((#{n\ 1895}# + (vector-length #{labelvec\ 1894}#))) + (let ((#{symnamevec\ 1896}# + (make-vector #{n\ 1895}#)) + (#{marksvec\ 1897}# + (make-vector #{n\ 1895}#))) + (begin + (letrec ((#{f\ 1898}# + (lambda (#{ids\ 1899}# #{i\ 1900}#) + (if (not (null? #{ids\ 1899}#)) + (call-with-values + (lambda () + (#{id-sym-name&marks\ 1298}# + (car #{ids\ 1899}#) + #{w\ 1893}#)) + (lambda (#{symname\ 1901}# + #{marks\ 1902}#) + (begin + (vector-set! + #{symnamevec\ 1896}# + #{i\ 1900}# + #{symname\ 1901}#) + (vector-set! + #{marksvec\ 1897}# + #{i\ 1900}# + #{marks\ 1902}#) + (#{f\ 1898}# + (cdr #{ids\ 1899}#) + (#{fx+\ 1254}# + #{i\ 1900}# + 1))))))))) + (#{f\ 1898}# #{ids\ 1891}# 0)) + (#{make-ribcage\ 1304}# + #{symnamevec\ 1896}# + #{marksvec\ 1897}# + #{labelvec\ 1894}#))))) + (#{wrap-subst\ 1301}# #{w\ 1893}#)))))) + (#{extend-ribcage!\ 1313}# + (lambda (#{ribcage\ 1903}# #{id\ 1904}# #{label\ 1905}#) + (begin + (#{set-ribcage-symnames!\ 1309}# + #{ribcage\ 1903}# + (cons (#{syntax-object-expression\ 1282}# #{id\ 1904}#) + (#{ribcage-symnames\ 1306}# #{ribcage\ 1903}#))) + (#{set-ribcage-marks!\ 1310}# + #{ribcage\ 1903}# + (cons (#{wrap-marks\ 1300}# + (#{syntax-object-wrap\ 1283}# #{id\ 1904}#)) + (#{ribcage-marks\ 1307}# #{ribcage\ 1903}#))) + (#{set-ribcage-labels!\ 1311}# + #{ribcage\ 1903}# + (cons #{label\ 1905}# + (#{ribcage-labels\ 1308}# #{ribcage\ 1903}#)))))) + (#{anti-mark\ 1312}# + (lambda (#{w\ 1906}#) + (#{make-wrap\ 1299}# + (cons #f (#{wrap-marks\ 1300}# #{w\ 1906}#)) + (cons 'shift + (#{wrap-subst\ 1301}# #{w\ 1906}#))))) + (#{set-ribcage-labels!\ 1311}# + (lambda (#{x\ 1907}# #{update\ 1908}#) + (vector-set! #{x\ 1907}# 3 #{update\ 1908}#))) + (#{set-ribcage-marks!\ 1310}# + (lambda (#{x\ 1909}# #{update\ 1910}#) + (vector-set! #{x\ 1909}# 2 #{update\ 1910}#))) + (#{set-ribcage-symnames!\ 1309}# + (lambda (#{x\ 1911}# #{update\ 1912}#) + (vector-set! #{x\ 1911}# 1 #{update\ 1912}#))) + (#{ribcage-labels\ 1308}# + (lambda (#{x\ 1913}#) (vector-ref #{x\ 1913}# 3))) + (#{ribcage-marks\ 1307}# + (lambda (#{x\ 1914}#) (vector-ref #{x\ 1914}# 2))) + (#{ribcage-symnames\ 1306}# + (lambda (#{x\ 1915}#) (vector-ref #{x\ 1915}# 1))) + (#{ribcage?\ 1305}# + (lambda (#{x\ 1916}#) + (if (vector? #{x\ 1916}#) + (if (= (vector-length #{x\ 1916}#) 4) + (eq? (vector-ref #{x\ 1916}# 0) (quote ribcage)) + #f) + #f))) + (#{make-ribcage\ 1304}# + (lambda (#{symnames\ 1917}# + #{marks\ 1918}# + #{labels\ 1919}#) + (vector + 'ribcage + #{symnames\ 1917}# + #{marks\ 1918}# + #{labels\ 1919}#))) + (#{gen-labels\ 1303}# + (lambda (#{ls\ 1920}#) + (if (null? #{ls\ 1920}#) + '() + (cons (#{gen-label\ 1302}#) + (#{gen-labels\ 1303}# (cdr #{ls\ 1920}#)))))) + (#{gen-label\ 1302}# (lambda () (string #\i))) + (#{wrap-subst\ 1301}# cdr) + (#{wrap-marks\ 1300}# car) + (#{make-wrap\ 1299}# cons) + (#{id-sym-name&marks\ 1298}# + (lambda (#{x\ 1921}# #{w\ 1922}#) + (if (#{syntax-object?\ 1281}# #{x\ 1921}#) + (values + (#{syntax-object-expression\ 1282}# #{x\ 1921}#) + (#{join-marks\ 1317}# + (#{wrap-marks\ 1300}# #{w\ 1922}#) + (#{wrap-marks\ 1300}# + (#{syntax-object-wrap\ 1283}# #{x\ 1921}#)))) + (values + #{x\ 1921}# + (#{wrap-marks\ 1300}# #{w\ 1922}#))))) + (#{id?\ 1297}# + (lambda (#{x\ 1923}#) + (if (symbol? #{x\ 1923}#) + #t + (if (#{syntax-object?\ 1281}# #{x\ 1923}#) + (symbol? + (#{syntax-object-expression\ 1282}# #{x\ 1923}#)) + #f)))) + (#{nonsymbol-id?\ 1296}# + (lambda (#{x\ 1924}#) + (if (#{syntax-object?\ 1281}# #{x\ 1924}#) + (symbol? + (#{syntax-object-expression\ 1282}# #{x\ 1924}#)) + #f))) + (#{global-extend\ 1295}# + (lambda (#{type\ 1925}# #{sym\ 1926}# #{val\ 1927}#) + (#{put-global-definition-hook\ 1260}# + #{sym\ 1926}# + #{type\ 1925}# + #{val\ 1927}#))) + (#{lookup\ 1294}# + (lambda (#{x\ 1928}# #{r\ 1929}# #{mod\ 1930}#) + (let ((#{t\ 1931}# (assq #{x\ 1928}# #{r\ 1929}#))) + (if #{t\ 1931}# + (cdr #{t\ 1931}#) + (if (symbol? #{x\ 1928}#) + (let ((#{t\ 1932}# + (#{get-global-definition-hook\ 1261}# + #{x\ 1928}# + #{mod\ 1930}#))) + (if #{t\ 1932}# #{t\ 1932}# (quote (global)))) + '(displaced-lexical)))))) + (#{macros-only-env\ 1293}# + (lambda (#{r\ 1933}#) + (if (null? #{r\ 1933}#) + '() + (let ((#{a\ 1934}# (car #{r\ 1933}#))) + (if (eq? (cadr #{a\ 1934}#) (quote macro)) + (cons #{a\ 1934}# + (#{macros-only-env\ 1293}# (cdr #{r\ 1933}#))) + (#{macros-only-env\ 1293}# (cdr #{r\ 1933}#))))))) + (#{extend-var-env\ 1292}# + (lambda (#{labels\ 1935}# #{vars\ 1936}# #{r\ 1937}#) + (if (null? #{labels\ 1935}#) + #{r\ 1937}# + (#{extend-var-env\ 1292}# + (cdr #{labels\ 1935}#) + (cdr #{vars\ 1936}#) + (cons (cons (car #{labels\ 1935}#) + (cons (quote lexical) (car #{vars\ 1936}#))) + #{r\ 1937}#))))) + (#{extend-env\ 1291}# + (lambda (#{labels\ 1938}# #{bindings\ 1939}# #{r\ 1940}#) + (if (null? #{labels\ 1938}#) + #{r\ 1940}# + (#{extend-env\ 1291}# + (cdr #{labels\ 1938}#) + (cdr #{bindings\ 1939}#) + (cons (cons (car #{labels\ 1938}#) + (car #{bindings\ 1939}#)) + #{r\ 1940}#))))) + (#{binding-value\ 1290}# cdr) + (#{binding-type\ 1289}# car) + (#{source-annotation\ 1288}# + (lambda (#{x\ 1941}#) + (if (#{syntax-object?\ 1281}# #{x\ 1941}#) + (#{source-annotation\ 1288}# + (#{syntax-object-expression\ 1282}# #{x\ 1941}#)) + (if (pair? #{x\ 1941}#) + (let ((#{props\ 1942}# (source-properties #{x\ 1941}#))) + (if (pair? #{props\ 1942}#) #{props\ 1942}# #f)) + #f)))) + (#{set-syntax-object-module!\ 1287}# + (lambda (#{x\ 1943}# #{update\ 1944}#) + (vector-set! #{x\ 1943}# 3 #{update\ 1944}#))) + (#{set-syntax-object-wrap!\ 1286}# + (lambda (#{x\ 1945}# #{update\ 1946}#) + (vector-set! #{x\ 1945}# 2 #{update\ 1946}#))) + (#{set-syntax-object-expression!\ 1285}# + (lambda (#{x\ 1947}# #{update\ 1948}#) + (vector-set! #{x\ 1947}# 1 #{update\ 1948}#))) + (#{syntax-object-module\ 1284}# + (lambda (#{x\ 1949}#) (vector-ref #{x\ 1949}# 3))) + (#{syntax-object-wrap\ 1283}# + (lambda (#{x\ 1950}#) (vector-ref #{x\ 1950}# 2))) + (#{syntax-object-expression\ 1282}# + (lambda (#{x\ 1951}#) (vector-ref #{x\ 1951}# 1))) + (#{syntax-object?\ 1281}# + (lambda (#{x\ 1952}#) + (if (vector? #{x\ 1952}#) + (if (= (vector-length #{x\ 1952}#) 4) + (eq? (vector-ref #{x\ 1952}# 0) + 'syntax-object) + #f) + #f))) + (#{make-syntax-object\ 1280}# + (lambda (#{expression\ 1953}# + #{wrap\ 1954}# + #{module\ 1955}#) + (vector + 'syntax-object + #{expression\ 1953}# + #{wrap\ 1954}# + #{module\ 1955}#))) + (#{build-letrec\ 1279}# + (lambda (#{src\ 1956}# + #{ids\ 1957}# + #{vars\ 1958}# + #{val-exps\ 1959}# + #{body-exp\ 1960}#) + (if (null? #{vars\ 1958}#) + #{body-exp\ 1960}# + (let ((#{atom-key\ 1961}# (fluid-ref #{*mode*\ 1253}#))) + (if (memv #{atom-key\ 1961}# (quote (c))) + (begin + (for-each + #{maybe-name-value!\ 1271}# + #{ids\ 1957}# + #{val-exps\ 1959}#) + ((@ (language tree-il) make-letrec) + #{src\ 1956}# + #{ids\ 1957}# + #{vars\ 1958}# + #{val-exps\ 1959}# + #{body-exp\ 1960}#)) + (#{decorate-source\ 1262}# + (list 'letrec + (map list #{vars\ 1958}# #{val-exps\ 1959}#) + #{body-exp\ 1960}#) + #{src\ 1956}#)))))) + (#{build-named-let\ 1278}# + (lambda (#{src\ 1962}# + #{ids\ 1963}# + #{vars\ 1964}# + #{val-exps\ 1965}# + #{body-exp\ 1966}#) + (let ((#{f\ 1967}# (car #{vars\ 1964}#)) + (#{f-name\ 1968}# (car #{ids\ 1963}#)) + (#{vars\ 1969}# (cdr #{vars\ 1964}#)) + (#{ids\ 1970}# (cdr #{ids\ 1963}#))) + (let ((#{atom-key\ 1971}# (fluid-ref #{*mode*\ 1253}#))) + (if (memv #{atom-key\ 1971}# (quote (c))) + (let ((#{proc\ 1972}# + (#{build-lambda\ 1273}# + #{src\ 1962}# + #{ids\ 1970}# + #{vars\ 1969}# + #f + #{body-exp\ 1966}#))) + (begin + (#{maybe-name-value!\ 1271}# + #{f-name\ 1968}# + #{proc\ 1972}#) + (for-each + #{maybe-name-value!\ 1271}# + #{ids\ 1970}# + #{val-exps\ 1965}#) + ((@ (language tree-il) make-letrec) + #{src\ 1962}# + (list #{f-name\ 1968}#) + (list #{f\ 1967}#) + (list #{proc\ 1972}#) + (#{build-application\ 1264}# + #{src\ 1962}# + (#{build-lexical-reference\ 1266}# + 'fun + #{src\ 1962}# + #{f-name\ 1968}# + #{f\ 1967}#) + #{val-exps\ 1965}#)))) + (#{decorate-source\ 1262}# + (list 'let + #{f\ 1967}# + (map list #{vars\ 1969}# #{val-exps\ 1965}#) + #{body-exp\ 1966}#) + #{src\ 1962}#)))))) + (#{build-let\ 1277}# + (lambda (#{src\ 1973}# + #{ids\ 1974}# + #{vars\ 1975}# + #{val-exps\ 1976}# + #{body-exp\ 1977}#) + (if (null? #{vars\ 1975}#) + #{body-exp\ 1977}# + (let ((#{atom-key\ 1978}# (fluid-ref #{*mode*\ 1253}#))) + (if (memv #{atom-key\ 1978}# (quote (c))) + (begin + (for-each + #{maybe-name-value!\ 1271}# + #{ids\ 1974}# + #{val-exps\ 1976}#) + ((@ (language tree-il) make-let) + #{src\ 1973}# + #{ids\ 1974}# + #{vars\ 1975}# + #{val-exps\ 1976}# + #{body-exp\ 1977}#)) + (#{decorate-source\ 1262}# + (list 'let + (map list #{vars\ 1975}# #{val-exps\ 1976}#) + #{body-exp\ 1977}#) + #{src\ 1973}#)))))) + (#{build-sequence\ 1276}# + (lambda (#{src\ 1979}# #{exps\ 1980}#) + (if (null? (cdr #{exps\ 1980}#)) + (car #{exps\ 1980}#) + (let ((#{atom-key\ 1981}# (fluid-ref #{*mode*\ 1253}#))) + (if (memv #{atom-key\ 1981}# (quote (c))) + ((@ (language tree-il) make-sequence) + #{src\ 1979}# + #{exps\ 1980}#) + (#{decorate-source\ 1262}# + (cons (quote begin) #{exps\ 1980}#) + #{src\ 1979}#)))))) + (#{build-data\ 1275}# + (lambda (#{src\ 1982}# #{exp\ 1983}#) + (let ((#{atom-key\ 1984}# (fluid-ref #{*mode*\ 1253}#))) + (if (memv #{atom-key\ 1984}# (quote (c))) + ((@ (language tree-il) make-const) + #{src\ 1982}# + #{exp\ 1983}#) + (#{decorate-source\ 1262}# + (if (if (self-evaluating? #{exp\ 1983}#) + (not (vector? #{exp\ 1983}#)) + #f) + #{exp\ 1983}# + (list (quote quote) #{exp\ 1983}#)) + #{src\ 1982}#))))) + (#{build-primref\ 1274}# + (lambda (#{src\ 1985}# #{name\ 1986}#) + (if (equal? + (module-name (current-module)) + '(guile)) + (let ((#{atom-key\ 1987}# (fluid-ref #{*mode*\ 1253}#))) + (if (memv #{atom-key\ 1987}# (quote (c))) + ((@ (language tree-il) make-toplevel-ref) + #{src\ 1985}# + #{name\ 1986}#) + (#{decorate-source\ 1262}# + #{name\ 1986}# + #{src\ 1985}#))) + (let ((#{atom-key\ 1988}# (fluid-ref #{*mode*\ 1253}#))) + (if (memv #{atom-key\ 1988}# (quote (c))) + ((@ (language tree-il) make-module-ref) + #{src\ 1985}# + '(guile) + #{name\ 1986}# + #f) + (#{decorate-source\ 1262}# + (list (quote @@) (quote (guile)) #{name\ 1986}#) + #{src\ 1985}#)))))) + (#{build-lambda\ 1273}# + (lambda (#{src\ 1989}# + #{ids\ 1990}# + #{vars\ 1991}# + #{docstring\ 1992}# + #{exp\ 1993}#) + (let ((#{atom-key\ 1994}# (fluid-ref #{*mode*\ 1253}#))) + (if (memv #{atom-key\ 1994}# (quote (c))) + ((@ (language tree-il) make-lambda) + #{src\ 1989}# + #{ids\ 1990}# + #{vars\ 1991}# + (if #{docstring\ 1992}# + (list (cons (quote documentation) #{docstring\ 1992}#)) + '()) + #{exp\ 1993}#) + (#{decorate-source\ 1262}# + (cons 'lambda + (cons #{vars\ 1991}# + (append + (if #{docstring\ 1992}# + (list #{docstring\ 1992}#) + '()) + (list #{exp\ 1993}#)))) + #{src\ 1989}#))))) + (#{build-global-definition\ 1272}# + (lambda (#{source\ 1995}# #{var\ 1996}# #{exp\ 1997}#) + (let ((#{atom-key\ 1998}# (fluid-ref #{*mode*\ 1253}#))) + (if (memv #{atom-key\ 1998}# (quote (c))) + (begin + (#{maybe-name-value!\ 1271}# + #{var\ 1996}# + #{exp\ 1997}#) + ((@ (language tree-il) make-toplevel-define) + #{source\ 1995}# + #{var\ 1996}# + #{exp\ 1997}#)) + (#{decorate-source\ 1262}# + (list (quote define) #{var\ 1996}# #{exp\ 1997}#) + #{source\ 1995}#))))) + (#{maybe-name-value!\ 1271}# + (lambda (#{name\ 1999}# #{val\ 2000}#) + (if ((@ (language tree-il) lambda?) #{val\ 2000}#) + (let ((#{meta\ 2001}# + ((@ (language tree-il) lambda-meta) + #{val\ 2000}#))) + (if (not (assq (quote name) #{meta\ 2001}#)) + ((setter (@ (language tree-il) lambda-meta)) + #{val\ 2000}# + (acons 'name + #{name\ 1999}# + #{meta\ 2001}#))))))) + (#{build-global-assignment\ 1270}# + (lambda (#{source\ 2002}# + #{var\ 2003}# + #{exp\ 2004}# + #{mod\ 2005}#) + (#{analyze-variable\ 1268}# + #{mod\ 2005}# + #{var\ 2003}# + (lambda (#{mod\ 2006}# #{var\ 2007}# #{public?\ 2008}#) + (let ((#{atom-key\ 2009}# (fluid-ref #{*mode*\ 1253}#))) + (if (memv #{atom-key\ 2009}# (quote (c))) + ((@ (language tree-il) make-module-set) + #{source\ 2002}# + #{mod\ 2006}# + #{var\ 2007}# + #{public?\ 2008}# + #{exp\ 2004}#) + (#{decorate-source\ 1262}# + (list 'set! + (list (if #{public?\ 2008}# + '@ + '@@) + #{mod\ 2006}# + #{var\ 2007}#) + #{exp\ 2004}#) + #{source\ 2002}#)))) + (lambda (#{var\ 2010}#) + (let ((#{atom-key\ 2011}# (fluid-ref #{*mode*\ 1253}#))) + (if (memv #{atom-key\ 2011}# (quote (c))) + ((@ (language tree-il) make-toplevel-set) + #{source\ 2002}# + #{var\ 2010}# + #{exp\ 2004}#) + (#{decorate-source\ 1262}# + (list (quote set!) #{var\ 2010}# #{exp\ 2004}#) + #{source\ 2002}#))))))) + (#{build-global-reference\ 1269}# + (lambda (#{source\ 2012}# #{var\ 2013}# #{mod\ 2014}#) + (#{analyze-variable\ 1268}# + #{mod\ 2014}# + #{var\ 2013}# + (lambda (#{mod\ 2015}# #{var\ 2016}# #{public?\ 2017}#) + (let ((#{atom-key\ 2018}# (fluid-ref #{*mode*\ 1253}#))) + (if (memv #{atom-key\ 2018}# (quote (c))) + ((@ (language tree-il) make-module-ref) + #{source\ 2012}# + #{mod\ 2015}# + #{var\ 2016}# + #{public?\ 2017}#) + (#{decorate-source\ 1262}# + (list (if #{public?\ 2017}# (quote @) (quote @@)) + #{mod\ 2015}# + #{var\ 2016}#) + #{source\ 2012}#)))) + (lambda (#{var\ 2019}#) + (let ((#{atom-key\ 2020}# (fluid-ref #{*mode*\ 1253}#))) + (if (memv #{atom-key\ 2020}# (quote (c))) + ((@ (language tree-il) make-toplevel-ref) + #{source\ 2012}# + #{var\ 2019}#) + (#{decorate-source\ 1262}# + #{var\ 2019}# + #{source\ 2012}#))))))) + (#{analyze-variable\ 1268}# + (lambda (#{mod\ 2021}# + #{var\ 2022}# + #{modref-cont\ 2023}# + #{bare-cont\ 2024}#) + (if (not #{mod\ 2021}#) + (#{bare-cont\ 2024}# #{var\ 2022}#) + (let ((#{kind\ 2025}# (car #{mod\ 2021}#)) + (#{mod\ 2026}# (cdr #{mod\ 2021}#))) + (if (memv #{kind\ 2025}# (quote (public))) + (#{modref-cont\ 2023}# + #{mod\ 2026}# + #{var\ 2022}# + #t) + (if (memv #{kind\ 2025}# (quote (private))) + (if (not (equal? + #{mod\ 2026}# + (module-name (current-module)))) + (#{modref-cont\ 2023}# + #{mod\ 2026}# + #{var\ 2022}# + #f) + (#{bare-cont\ 2024}# #{var\ 2022}#)) + (if (memv #{kind\ 2025}# (quote (bare))) + (#{bare-cont\ 2024}# #{var\ 2022}#) + (if (memv #{kind\ 2025}# (quote (hygiene))) + (if (if (not (equal? + #{mod\ 2026}# + (module-name (current-module)))) + (module-variable + (resolve-module #{mod\ 2026}#) + #{var\ 2022}#) + #f) + (#{modref-cont\ 2023}# + #{mod\ 2026}# + #{var\ 2022}# + #f) + (#{bare-cont\ 2024}# #{var\ 2022}#)) + (syntax-violation + #f + "bad module kind" + #{var\ 2022}# + #{mod\ 2026}#))))))))) + (#{build-lexical-assignment\ 1267}# + (lambda (#{source\ 2027}# + #{name\ 2028}# + #{var\ 2029}# + #{exp\ 2030}#) + (let ((#{atom-key\ 2031}# (fluid-ref #{*mode*\ 1253}#))) + (if (memv #{atom-key\ 2031}# (quote (c))) + ((@ (language tree-il) make-lexical-set) + #{source\ 2027}# + #{name\ 2028}# + #{var\ 2029}# + #{exp\ 2030}#) + (#{decorate-source\ 1262}# + (list (quote set!) #{var\ 2029}# #{exp\ 2030}#) + #{source\ 2027}#))))) + (#{build-lexical-reference\ 1266}# + (lambda (#{type\ 2032}# + #{source\ 2033}# + #{name\ 2034}# + #{var\ 2035}#) + (let ((#{atom-key\ 2036}# (fluid-ref #{*mode*\ 1253}#))) + (if (memv #{atom-key\ 2036}# (quote (c))) + ((@ (language tree-il) make-lexical-ref) + #{source\ 2033}# + #{name\ 2034}# + #{var\ 2035}#) + (#{decorate-source\ 1262}# + #{var\ 2035}# + #{source\ 2033}#))))) + (#{build-conditional\ 1265}# + (lambda (#{source\ 2037}# + #{test-exp\ 2038}# + #{then-exp\ 2039}# + #{else-exp\ 2040}#) + (let ((#{atom-key\ 2041}# (fluid-ref #{*mode*\ 1253}#))) + (if (memv #{atom-key\ 2041}# (quote (c))) + ((@ (language tree-il) make-conditional) + #{source\ 2037}# + #{test-exp\ 2038}# + #{then-exp\ 2039}# + #{else-exp\ 2040}#) + (#{decorate-source\ 1262}# + (if (equal? #{else-exp\ 2040}# (quote (if #f #f))) + (list 'if + #{test-exp\ 2038}# + #{then-exp\ 2039}#) + (list 'if + #{test-exp\ 2038}# + #{then-exp\ 2039}# + #{else-exp\ 2040}#)) + #{source\ 2037}#))))) + (#{build-application\ 1264}# + (lambda (#{source\ 2042}# + #{fun-exp\ 2043}# + #{arg-exps\ 2044}#) + (let ((#{atom-key\ 2045}# (fluid-ref #{*mode*\ 1253}#))) + (if (memv #{atom-key\ 2045}# (quote (c))) + ((@ (language tree-il) make-application) + #{source\ 2042}# + #{fun-exp\ 2043}# + #{arg-exps\ 2044}#) + (#{decorate-source\ 1262}# + (cons #{fun-exp\ 2043}# #{arg-exps\ 2044}#) + #{source\ 2042}#))))) + (#{build-void\ 1263}# + (lambda (#{source\ 2046}#) + (let ((#{atom-key\ 2047}# (fluid-ref #{*mode*\ 1253}#))) + (if (memv #{atom-key\ 2047}# (quote (c))) + ((@ (language tree-il) make-void) + #{source\ 2046}#) + (#{decorate-source\ 1262}# + '(if #f #f) + #{source\ 2046}#))))) + (#{decorate-source\ 1262}# + (lambda (#{e\ 2048}# #{s\ 2049}#) + (begin + (if (if (pair? #{e\ 2048}#) #{s\ 2049}# #f) + (set-source-properties! #{e\ 2048}# #{s\ 2049}#)) + #{e\ 2048}#))) + (#{get-global-definition-hook\ 1261}# + (lambda (#{symbol\ 2050}# #{module\ 2051}#) + (begin + (if (if (not #{module\ 2051}#) (current-module) #f) + (warn "module system is booted, we should have a module" + #{symbol\ 2050}#)) + (let ((#{v\ 2052}# + (module-variable + (if #{module\ 2051}# + (resolve-module (cdr #{module\ 2051}#)) + (current-module)) + #{symbol\ 2050}#))) + (if #{v\ 2052}# + (if (variable-bound? #{v\ 2052}#) + (let ((#{val\ 2053}# (variable-ref #{v\ 2052}#))) + (if (macro? #{val\ 2053}#) + (if (syncase-macro-type #{val\ 2053}#) + (cons (syncase-macro-type #{val\ 2053}#) + (syncase-macro-binding #{val\ 2053}#)) + #f) + #f)) + #f) + #f))))) + (#{put-global-definition-hook\ 1260}# + (lambda (#{symbol\ 2054}# #{type\ 2055}# #{val\ 2056}#) + (let ((#{existing\ 2057}# + (let ((#{v\ 2058}# + (module-variable + (current-module) + #{symbol\ 2054}#))) + (if #{v\ 2058}# + (if (variable-bound? #{v\ 2058}#) + (let ((#{val\ 2059}# (variable-ref #{v\ 2058}#))) + (if (macro? #{val\ 2059}#) + (if (not (syncase-macro-type #{val\ 2059}#)) + #{val\ 2059}# + #f) + #f)) + #f) + #f)))) + (module-define! + (current-module) + #{symbol\ 2054}# + (if #{existing\ 2057}# + (make-extended-syncase-macro + #{existing\ 2057}# + #{type\ 2055}# + #{val\ 2056}#) + (make-syncase-macro #{type\ 2055}# #{val\ 2056}#)))))) + (#{local-eval-hook\ 1259}# + (lambda (#{x\ 2060}# #{mod\ 2061}#) + (primitive-eval + (list #{noexpand\ 1252}# + (let ((#{atom-key\ 2062}# (fluid-ref #{*mode*\ 1253}#))) + (if (memv #{atom-key\ 2062}# (quote (c))) + ((@ (language tree-il) tree-il->scheme) + #{x\ 2060}#) + #{x\ 2060}#)))))) + (#{top-level-eval-hook\ 1258}# + (lambda (#{x\ 2063}# #{mod\ 2064}#) + (primitive-eval + (list #{noexpand\ 1252}# + (let ((#{atom-key\ 2065}# (fluid-ref #{*mode*\ 1253}#))) + (if (memv #{atom-key\ 2065}# (quote (c))) + ((@ (language tree-il) tree-il->scheme) + #{x\ 2063}#) + #{x\ 2063}#)))))) + (#{fx<\ 1257}# <) + (#{fx=\ 1256}# =) + (#{fx-\ 1255}# -) + (#{fx+\ 1254}# +) + (#{*mode*\ 1253}# (make-fluid)) + (#{noexpand\ 1252}# "noexpand")) + (begin + (#{global-extend\ 1295}# + 'local-syntax + 'letrec-syntax + #t) + (#{global-extend\ 1295}# + 'local-syntax + 'let-syntax + #f) + (#{global-extend\ 1295}# + 'core + 'fluid-let-syntax + (lambda (#{e\ 2066}# + #{r\ 2067}# + #{w\ 2068}# + #{s\ 2069}# + #{mod\ 2070}#) + ((lambda (#{tmp\ 2071}#) + ((lambda (#{tmp\ 2072}#) + (if (if #{tmp\ 2072}# + (apply (lambda (#{_\ 2073}# + #{var\ 2074}# + #{val\ 2075}# + #{e1\ 2076}# + #{e2\ 2077}#) + (#{valid-bound-ids?\ 1322}# #{var\ 2074}#)) + #{tmp\ 2072}#) + #f) + (apply (lambda (#{_\ 2079}# + #{var\ 2080}# + #{val\ 2081}# + #{e1\ 2082}# + #{e2\ 2083}#) + (let ((#{names\ 2084}# + (map (lambda (#{x\ 2085}#) + (#{id-var-name\ 1319}# + #{x\ 2085}# + #{w\ 2068}#)) + #{var\ 2080}#))) + (begin + (for-each + (lambda (#{id\ 2087}# #{n\ 2088}#) + (let ((#{atom-key\ 2089}# + (#{binding-type\ 1289}# + (#{lookup\ 1294}# + #{n\ 2088}# + #{r\ 2067}# + #{mod\ 2070}#)))) + (if (memv #{atom-key\ 2089}# + '(displaced-lexical)) + (syntax-violation + 'fluid-let-syntax + "identifier out of context" + #{e\ 2066}# + (#{source-wrap\ 1326}# + #{id\ 2087}# + #{w\ 2068}# + #{s\ 2069}# + #{mod\ 2070}#))))) + #{var\ 2080}# + #{names\ 2084}#) + (#{chi-body\ 1337}# + (cons #{e1\ 2082}# #{e2\ 2083}#) + (#{source-wrap\ 1326}# + #{e\ 2066}# + #{w\ 2068}# + #{s\ 2069}# + #{mod\ 2070}#) + (#{extend-env\ 1291}# + #{names\ 2084}# + (let ((#{trans-r\ 2092}# + (#{macros-only-env\ 1293}# + #{r\ 2067}#))) + (map (lambda (#{x\ 2093}#) + (cons 'macro + (#{eval-local-transformer\ 1340}# + (#{chi\ 1333}# + #{x\ 2093}# + #{trans-r\ 2092}# + #{w\ 2068}# + #{mod\ 2070}#) + #{mod\ 2070}#))) + #{val\ 2081}#)) + #{r\ 2067}#) + #{w\ 2068}# + #{mod\ 2070}#)))) + #{tmp\ 2072}#) + ((lambda (#{_\ 2095}#) + (syntax-violation + 'fluid-let-syntax + "bad syntax" + (#{source-wrap\ 1326}# + #{e\ 2066}# + #{w\ 2068}# + #{s\ 2069}# + #{mod\ 2070}#))) + #{tmp\ 2071}#))) + ($sc-dispatch + #{tmp\ 2071}# + '(any #(each (any any)) any . each-any)))) + #{e\ 2066}#))) + (#{global-extend\ 1295}# + 'core + 'quote + (lambda (#{e\ 2096}# + #{r\ 2097}# + #{w\ 2098}# + #{s\ 2099}# + #{mod\ 2100}#) + ((lambda (#{tmp\ 2101}#) + ((lambda (#{tmp\ 2102}#) + (if #{tmp\ 2102}# + (apply (lambda (#{_\ 2103}# #{e\ 2104}#) + (#{build-data\ 1275}# + #{s\ 2099}# + (#{strip\ 1343}# #{e\ 2104}# #{w\ 2098}#))) + #{tmp\ 2102}#) + ((lambda (#{_\ 2105}#) + (syntax-violation + 'quote + "bad syntax" + (#{source-wrap\ 1326}# + #{e\ 2096}# + #{w\ 2098}# + #{s\ 2099}# + #{mod\ 2100}#))) + #{tmp\ 2101}#))) + ($sc-dispatch #{tmp\ 2101}# (quote (any any))))) + #{e\ 2096}#))) + (#{global-extend\ 1295}# + 'core + 'syntax + (letrec ((#{regen\ 2113}# + (lambda (#{x\ 2114}#) + (let ((#{atom-key\ 2115}# (car #{x\ 2114}#))) + (if (memv #{atom-key\ 2115}# (quote (ref))) + (#{build-lexical-reference\ 1266}# + 'value + #f + (cadr #{x\ 2114}#) + (cadr #{x\ 2114}#)) + (if (memv #{atom-key\ 2115}# (quote (primitive))) + (#{build-primref\ 1274}# #f (cadr #{x\ 2114}#)) + (if (memv #{atom-key\ 2115}# (quote (quote))) + (#{build-data\ 1275}# #f (cadr #{x\ 2114}#)) + (if (memv #{atom-key\ 2115}# (quote (lambda))) + (#{build-lambda\ 1273}# + #f + (cadr #{x\ 2114}#) + (cadr #{x\ 2114}#) + #f + (#{regen\ 2113}# (caddr #{x\ 2114}#))) + (#{build-application\ 1264}# + #f + (#{build-primref\ 1274}# #f (car #{x\ 2114}#)) + (map #{regen\ 2113}# + (cdr #{x\ 2114}#)))))))))) + (#{gen-vector\ 2112}# + (lambda (#{x\ 2116}#) + (if (eq? (car #{x\ 2116}#) (quote list)) + (cons (quote vector) (cdr #{x\ 2116}#)) + (if (eq? (car #{x\ 2116}#) (quote quote)) + (list 'quote + (list->vector (cadr #{x\ 2116}#))) + (list (quote list->vector) #{x\ 2116}#))))) + (#{gen-append\ 2111}# + (lambda (#{x\ 2117}# #{y\ 2118}#) + (if (equal? #{y\ 2118}# (quote (quote ()))) + #{x\ 2117}# + (list (quote append) #{x\ 2117}# #{y\ 2118}#)))) + (#{gen-cons\ 2110}# + (lambda (#{x\ 2119}# #{y\ 2120}#) + (let ((#{atom-key\ 2121}# (car #{y\ 2120}#))) + (if (memv #{atom-key\ 2121}# (quote (quote))) + (if (eq? (car #{x\ 2119}#) (quote quote)) + (list 'quote + (cons (cadr #{x\ 2119}#) (cadr #{y\ 2120}#))) + (if (eq? (cadr #{y\ 2120}#) (quote ())) + (list (quote list) #{x\ 2119}#) + (list (quote cons) #{x\ 2119}# #{y\ 2120}#))) + (if (memv #{atom-key\ 2121}# (quote (list))) + (cons 'list + (cons #{x\ 2119}# (cdr #{y\ 2120}#))) + (list (quote cons) #{x\ 2119}# #{y\ 2120}#)))))) + (#{gen-map\ 2109}# + (lambda (#{e\ 2122}# #{map-env\ 2123}#) + (let ((#{formals\ 2124}# (map cdr #{map-env\ 2123}#)) + (#{actuals\ 2125}# + (map (lambda (#{x\ 2126}#) + (list (quote ref) (car #{x\ 2126}#))) + #{map-env\ 2123}#))) + (if (eq? (car #{e\ 2122}#) (quote ref)) + (car #{actuals\ 2125}#) + (if (and-map + (lambda (#{x\ 2127}#) + (if (eq? (car #{x\ 2127}#) (quote ref)) + (memq (cadr #{x\ 2127}#) #{formals\ 2124}#) + #f)) + (cdr #{e\ 2122}#)) + (cons 'map + (cons (list 'primitive + (car #{e\ 2122}#)) + (map (let ((#{r\ 2128}# + (map cons + #{formals\ 2124}# + #{actuals\ 2125}#))) + (lambda (#{x\ 2129}#) + (cdr (assq (cadr #{x\ 2129}#) + #{r\ 2128}#)))) + (cdr #{e\ 2122}#)))) + (cons 'map + (cons (list 'lambda + #{formals\ 2124}# + #{e\ 2122}#) + #{actuals\ 2125}#))))))) + (#{gen-mappend\ 2108}# + (lambda (#{e\ 2130}# #{map-env\ 2131}#) + (list 'apply + '(primitive append) + (#{gen-map\ 2109}# #{e\ 2130}# #{map-env\ 2131}#)))) + (#{gen-ref\ 2107}# + (lambda (#{src\ 2132}# + #{var\ 2133}# + #{level\ 2134}# + #{maps\ 2135}#) + (if (#{fx=\ 1256}# #{level\ 2134}# 0) + (values #{var\ 2133}# #{maps\ 2135}#) + (if (null? #{maps\ 2135}#) + (syntax-violation + 'syntax + "missing ellipsis" + #{src\ 2132}#) + (call-with-values + (lambda () + (#{gen-ref\ 2107}# + #{src\ 2132}# + #{var\ 2133}# + (#{fx-\ 1255}# #{level\ 2134}# 1) + (cdr #{maps\ 2135}#))) + (lambda (#{outer-var\ 2136}# #{outer-maps\ 2137}#) + (let ((#{b\ 2138}# + (assq #{outer-var\ 2136}# + (car #{maps\ 2135}#)))) + (if #{b\ 2138}# + (values (cdr #{b\ 2138}#) #{maps\ 2135}#) + (let ((#{inner-var\ 2139}# + (#{gen-var\ 1344}# (quote tmp)))) + (values + #{inner-var\ 2139}# + (cons (cons (cons #{outer-var\ 2136}# + #{inner-var\ 2139}#) + (car #{maps\ 2135}#)) + #{outer-maps\ 2137}#))))))))))) + (#{gen-syntax\ 2106}# + (lambda (#{src\ 2140}# + #{e\ 2141}# + #{r\ 2142}# + #{maps\ 2143}# + #{ellipsis?\ 2144}# + #{mod\ 2145}#) + (if (#{id?\ 1297}# #{e\ 2141}#) + (let ((#{label\ 2146}# + (#{id-var-name\ 1319}# + #{e\ 2141}# + '(())))) + (let ((#{b\ 2147}# + (#{lookup\ 1294}# + #{label\ 2146}# + #{r\ 2142}# + #{mod\ 2145}#))) + (if (eq? (#{binding-type\ 1289}# #{b\ 2147}#) + 'syntax) + (call-with-values + (lambda () + (let ((#{var.lev\ 2148}# + (#{binding-value\ 1290}# + #{b\ 2147}#))) + (#{gen-ref\ 2107}# + #{src\ 2140}# + (car #{var.lev\ 2148}#) + (cdr #{var.lev\ 2148}#) + #{maps\ 2143}#))) + (lambda (#{var\ 2149}# #{maps\ 2150}#) + (values + (list (quote ref) #{var\ 2149}#) + #{maps\ 2150}#))) + (if (#{ellipsis?\ 2144}# #{e\ 2141}#) + (syntax-violation + 'syntax + "misplaced ellipsis" + #{src\ 2140}#) + (values + (list (quote quote) #{e\ 2141}#) + #{maps\ 2143}#))))) + ((lambda (#{tmp\ 2151}#) + ((lambda (#{tmp\ 2152}#) + (if (if #{tmp\ 2152}# + (apply (lambda (#{dots\ 2153}# #{e\ 2154}#) + (#{ellipsis?\ 2144}# + #{dots\ 2153}#)) + #{tmp\ 2152}#) + #f) + (apply (lambda (#{dots\ 2155}# #{e\ 2156}#) + (#{gen-syntax\ 2106}# + #{src\ 2140}# + #{e\ 2156}# + #{r\ 2142}# + #{maps\ 2143}# + (lambda (#{x\ 2157}#) #f) + #{mod\ 2145}#)) + #{tmp\ 2152}#) + ((lambda (#{tmp\ 2158}#) + (if (if #{tmp\ 2158}# + (apply (lambda (#{x\ 2159}# + #{dots\ 2160}# + #{y\ 2161}#) + (#{ellipsis?\ 2144}# + #{dots\ 2160}#)) + #{tmp\ 2158}#) + #f) + (apply (lambda (#{x\ 2162}# + #{dots\ 2163}# + #{y\ 2164}#) + (letrec ((#{f\ 2165}# + (lambda (#{y\ 2166}# + #{k\ 2167}#) + ((lambda (#{tmp\ 2171}#) + ((lambda (#{tmp\ 2172}#) + (if (if #{tmp\ 2172}# + (apply (lambda (#{dots\ 2173}# + #{y\ 2174}#) + (#{ellipsis?\ 2144}# + #{dots\ 2173}#)) + #{tmp\ 2172}#) + #f) + (apply (lambda (#{dots\ 2175}# + #{y\ 2176}#) + (#{f\ 2165}# + #{y\ 2176}# + (lambda (#{maps\ 2177}#) + (call-with-values + (lambda () + (#{k\ 2167}# + (cons '() + #{maps\ 2177}#))) + (lambda (#{x\ 2178}# + #{maps\ 2179}#) + (if (null? (car #{maps\ 2179}#)) + (syntax-violation + 'syntax + "extra ellipsis" + #{src\ 2140}#) + (values + (#{gen-mappend\ 2108}# + #{x\ 2178}# + (car #{maps\ 2179}#)) + (cdr #{maps\ 2179}#)))))))) + #{tmp\ 2172}#) + ((lambda (#{_\ 2180}#) + (call-with-values + (lambda () + (#{gen-syntax\ 2106}# + #{src\ 2140}# + #{y\ 2166}# + #{r\ 2142}# + #{maps\ 2143}# + #{ellipsis?\ 2144}# + #{mod\ 2145}#)) + (lambda (#{y\ 2181}# + #{maps\ 2182}#) + (call-with-values + (lambda () + (#{k\ 2167}# + #{maps\ 2182}#)) + (lambda (#{x\ 2183}# + #{maps\ 2184}#) + (values + (#{gen-append\ 2111}# + #{x\ 2183}# + #{y\ 2181}#) + #{maps\ 2184}#)))))) + #{tmp\ 2171}#))) + ($sc-dispatch + #{tmp\ 2171}# + '(any . any)))) + #{y\ 2166}#)))) + (#{f\ 2165}# + #{y\ 2164}# + (lambda (#{maps\ 2168}#) + (call-with-values + (lambda () + (#{gen-syntax\ 2106}# + #{src\ 2140}# + #{x\ 2162}# + #{r\ 2142}# + (cons '() + #{maps\ 2168}#) + #{ellipsis?\ 2144}# + #{mod\ 2145}#)) + (lambda (#{x\ 2169}# + #{maps\ 2170}#) + (if (null? (car #{maps\ 2170}#)) + (syntax-violation + 'syntax + "extra ellipsis" + #{src\ 2140}#) + (values + (#{gen-map\ 2109}# + #{x\ 2169}# + (car #{maps\ 2170}#)) + (cdr #{maps\ 2170}#))))))))) + #{tmp\ 2158}#) + ((lambda (#{tmp\ 2185}#) + (if #{tmp\ 2185}# + (apply (lambda (#{x\ 2186}# + #{y\ 2187}#) + (call-with-values + (lambda () + (#{gen-syntax\ 2106}# + #{src\ 2140}# + #{x\ 2186}# + #{r\ 2142}# + #{maps\ 2143}# + #{ellipsis?\ 2144}# + #{mod\ 2145}#)) + (lambda (#{x\ 2188}# + #{maps\ 2189}#) + (call-with-values + (lambda () + (#{gen-syntax\ 2106}# + #{src\ 2140}# + #{y\ 2187}# + #{r\ 2142}# + #{maps\ 2189}# + #{ellipsis?\ 2144}# + #{mod\ 2145}#)) + (lambda (#{y\ 2190}# + #{maps\ 2191}#) + (values + (#{gen-cons\ 2110}# + #{x\ 2188}# + #{y\ 2190}#) + #{maps\ 2191}#)))))) + #{tmp\ 2185}#) + ((lambda (#{tmp\ 2192}#) + (if #{tmp\ 2192}# + (apply (lambda (#{e1\ 2193}# + #{e2\ 2194}#) + (call-with-values + (lambda () + (#{gen-syntax\ 2106}# + #{src\ 2140}# + (cons #{e1\ 2193}# + #{e2\ 2194}#) + #{r\ 2142}# + #{maps\ 2143}# + #{ellipsis?\ 2144}# + #{mod\ 2145}#)) + (lambda (#{e\ 2196}# + #{maps\ 2197}#) + (values + (#{gen-vector\ 2112}# + #{e\ 2196}#) + #{maps\ 2197}#)))) + #{tmp\ 2192}#) + ((lambda (#{_\ 2198}#) + (values + (list 'quote + #{e\ 2141}#) + #{maps\ 2143}#)) + #{tmp\ 2151}#))) + ($sc-dispatch + #{tmp\ 2151}# + '#(vector (any . each-any)))))) + ($sc-dispatch + #{tmp\ 2151}# + '(any . any))))) + ($sc-dispatch + #{tmp\ 2151}# + '(any any . any))))) + ($sc-dispatch #{tmp\ 2151}# (quote (any any))))) + #{e\ 2141}#))))) + (lambda (#{e\ 2199}# + #{r\ 2200}# + #{w\ 2201}# + #{s\ 2202}# + #{mod\ 2203}#) + (let ((#{e\ 2204}# + (#{source-wrap\ 1326}# + #{e\ 2199}# + #{w\ 2201}# + #{s\ 2202}# + #{mod\ 2203}#))) + ((lambda (#{tmp\ 2205}#) + ((lambda (#{tmp\ 2206}#) + (if #{tmp\ 2206}# + (apply (lambda (#{_\ 2207}# #{x\ 2208}#) + (call-with-values + (lambda () + (#{gen-syntax\ 2106}# + #{e\ 2204}# + #{x\ 2208}# + #{r\ 2200}# + '() + #{ellipsis?\ 1342}# + #{mod\ 2203}#)) + (lambda (#{e\ 2209}# #{maps\ 2210}#) + (#{regen\ 2113}# #{e\ 2209}#)))) + #{tmp\ 2206}#) + ((lambda (#{_\ 2211}#) + (syntax-violation + 'syntax + "bad `syntax' form" + #{e\ 2204}#)) + #{tmp\ 2205}#))) + ($sc-dispatch #{tmp\ 2205}# (quote (any any))))) + #{e\ 2204}#))))) + (#{global-extend\ 1295}# + 'core + 'lambda + (lambda (#{e\ 2212}# + #{r\ 2213}# + #{w\ 2214}# + #{s\ 2215}# + #{mod\ 2216}#) + ((lambda (#{tmp\ 2217}#) + ((lambda (#{tmp\ 2218}#) + (if #{tmp\ 2218}# + (apply (lambda (#{_\ 2219}# #{c\ 2220}#) + (#{chi-lambda-clause\ 1338}# + (#{source-wrap\ 1326}# + #{e\ 2212}# + #{w\ 2214}# + #{s\ 2215}# + #{mod\ 2216}#) + #f + #{c\ 2220}# + #{r\ 2213}# + #{w\ 2214}# + #{mod\ 2216}# + (lambda (#{names\ 2221}# + #{vars\ 2222}# + #{docstring\ 2223}# + #{body\ 2224}#) + (#{build-lambda\ 1273}# + #{s\ 2215}# + #{names\ 2221}# + #{vars\ 2222}# + #{docstring\ 2223}# + #{body\ 2224}#)))) + #{tmp\ 2218}#) + (syntax-violation + #f + "source expression failed to match any pattern" + #{tmp\ 2217}#))) + ($sc-dispatch #{tmp\ 2217}# (quote (any . any))))) + #{e\ 2212}#))) + (#{global-extend\ 1295}# + 'core + 'let + (letrec ((#{chi-let\ 2225}# + (lambda (#{e\ 2226}# + #{r\ 2227}# + #{w\ 2228}# + #{s\ 2229}# + #{mod\ 2230}# + #{constructor\ 2231}# + #{ids\ 2232}# + #{vals\ 2233}# + #{exps\ 2234}#) + (if (not (#{valid-bound-ids?\ 1322}# #{ids\ 2232}#)) + (syntax-violation + 'let + "duplicate bound variable" + #{e\ 2226}#) + (let ((#{labels\ 2235}# + (#{gen-labels\ 1303}# #{ids\ 2232}#)) + (#{new-vars\ 2236}# + (map #{gen-var\ 1344}# #{ids\ 2232}#))) + (let ((#{nw\ 2237}# + (#{make-binding-wrap\ 1314}# + #{ids\ 2232}# + #{labels\ 2235}# + #{w\ 2228}#)) + (#{nr\ 2238}# + (#{extend-var-env\ 1292}# + #{labels\ 2235}# + #{new-vars\ 2236}# + #{r\ 2227}#))) + (#{constructor\ 2231}# + #{s\ 2229}# + (map syntax->datum #{ids\ 2232}#) + #{new-vars\ 2236}# + (map (lambda (#{x\ 2239}#) + (#{chi\ 1333}# + #{x\ 2239}# + #{r\ 2227}# + #{w\ 2228}# + #{mod\ 2230}#)) + #{vals\ 2233}#) + (#{chi-body\ 1337}# + #{exps\ 2234}# + (#{source-wrap\ 1326}# + #{e\ 2226}# + #{nw\ 2237}# + #{s\ 2229}# + #{mod\ 2230}#) + #{nr\ 2238}# + #{nw\ 2237}# + #{mod\ 2230}#)))))))) + (lambda (#{e\ 2240}# + #{r\ 2241}# + #{w\ 2242}# + #{s\ 2243}# + #{mod\ 2244}#) + ((lambda (#{tmp\ 2245}#) + ((lambda (#{tmp\ 2246}#) + (if (if #{tmp\ 2246}# + (apply (lambda (#{_\ 2247}# + #{id\ 2248}# + #{val\ 2249}# + #{e1\ 2250}# + #{e2\ 2251}#) + (and-map #{id?\ 1297}# #{id\ 2248}#)) + #{tmp\ 2246}#) + #f) + (apply (lambda (#{_\ 2253}# + #{id\ 2254}# + #{val\ 2255}# + #{e1\ 2256}# + #{e2\ 2257}#) + (#{chi-let\ 2225}# + #{e\ 2240}# + #{r\ 2241}# + #{w\ 2242}# + #{s\ 2243}# + #{mod\ 2244}# + #{build-let\ 1277}# + #{id\ 2254}# + #{val\ 2255}# + (cons #{e1\ 2256}# #{e2\ 2257}#))) + #{tmp\ 2246}#) + ((lambda (#{tmp\ 2261}#) + (if (if #{tmp\ 2261}# + (apply (lambda (#{_\ 2262}# + #{f\ 2263}# + #{id\ 2264}# + #{val\ 2265}# + #{e1\ 2266}# + #{e2\ 2267}#) + (if (#{id?\ 1297}# #{f\ 2263}#) + (and-map #{id?\ 1297}# #{id\ 2264}#) + #f)) + #{tmp\ 2261}#) + #f) + (apply (lambda (#{_\ 2269}# + #{f\ 2270}# + #{id\ 2271}# + #{val\ 2272}# + #{e1\ 2273}# + #{e2\ 2274}#) + (#{chi-let\ 2225}# + #{e\ 2240}# + #{r\ 2241}# + #{w\ 2242}# + #{s\ 2243}# + #{mod\ 2244}# + #{build-named-let\ 1278}# + (cons #{f\ 2270}# #{id\ 2271}#) + #{val\ 2272}# + (cons #{e1\ 2273}# #{e2\ 2274}#))) + #{tmp\ 2261}#) + ((lambda (#{_\ 2278}#) + (syntax-violation + 'let + "bad let" + (#{source-wrap\ 1326}# + #{e\ 2240}# + #{w\ 2242}# + #{s\ 2243}# + #{mod\ 2244}#))) + #{tmp\ 2245}#))) + ($sc-dispatch + #{tmp\ 2245}# + '(any any #(each (any any)) any . each-any))))) + ($sc-dispatch + #{tmp\ 2245}# + '(any #(each (any any)) any . each-any)))) + #{e\ 2240}#)))) + (#{global-extend\ 1295}# + 'core + 'letrec + (lambda (#{e\ 2279}# + #{r\ 2280}# + #{w\ 2281}# + #{s\ 2282}# + #{mod\ 2283}#) + ((lambda (#{tmp\ 2284}#) + ((lambda (#{tmp\ 2285}#) + (if (if #{tmp\ 2285}# + (apply (lambda (#{_\ 2286}# + #{id\ 2287}# + #{val\ 2288}# + #{e1\ 2289}# + #{e2\ 2290}#) + (and-map #{id?\ 1297}# #{id\ 2287}#)) + #{tmp\ 2285}#) + #f) + (apply (lambda (#{_\ 2292}# + #{id\ 2293}# + #{val\ 2294}# + #{e1\ 2295}# + #{e2\ 2296}#) + (let ((#{ids\ 2297}# #{id\ 2293}#)) + (if (not (#{valid-bound-ids?\ 1322}# + #{ids\ 2297}#)) + (syntax-violation + 'letrec + "duplicate bound variable" + #{e\ 2279}#) + (let ((#{labels\ 2299}# + (#{gen-labels\ 1303}# #{ids\ 2297}#)) + (#{new-vars\ 2300}# + (map #{gen-var\ 1344}# #{ids\ 2297}#))) + (let ((#{w\ 2301}# + (#{make-binding-wrap\ 1314}# + #{ids\ 2297}# + #{labels\ 2299}# + #{w\ 2281}#)) + (#{r\ 2302}# + (#{extend-var-env\ 1292}# + #{labels\ 2299}# + #{new-vars\ 2300}# + #{r\ 2280}#))) + (#{build-letrec\ 1279}# + #{s\ 2282}# + (map syntax->datum #{ids\ 2297}#) + #{new-vars\ 2300}# + (map (lambda (#{x\ 2303}#) + (#{chi\ 1333}# + #{x\ 2303}# + #{r\ 2302}# + #{w\ 2301}# + #{mod\ 2283}#)) + #{val\ 2294}#) + (#{chi-body\ 1337}# + (cons #{e1\ 2295}# #{e2\ 2296}#) + (#{source-wrap\ 1326}# + #{e\ 2279}# + #{w\ 2301}# + #{s\ 2282}# + #{mod\ 2283}#) + #{r\ 2302}# + #{w\ 2301}# + #{mod\ 2283}#))))))) + #{tmp\ 2285}#) + ((lambda (#{_\ 2306}#) + (syntax-violation + 'letrec + "bad letrec" + (#{source-wrap\ 1326}# + #{e\ 2279}# + #{w\ 2281}# + #{s\ 2282}# + #{mod\ 2283}#))) + #{tmp\ 2284}#))) + ($sc-dispatch + #{tmp\ 2284}# + '(any #(each (any any)) any . each-any)))) + #{e\ 2279}#))) + (#{global-extend\ 1295}# + 'core + 'set! + (lambda (#{e\ 2307}# + #{r\ 2308}# + #{w\ 2309}# + #{s\ 2310}# + #{mod\ 2311}#) + ((lambda (#{tmp\ 2312}#) + ((lambda (#{tmp\ 2313}#) + (if (if #{tmp\ 2313}# + (apply (lambda (#{_\ 2314}# #{id\ 2315}# #{val\ 2316}#) + (#{id?\ 1297}# #{id\ 2315}#)) + #{tmp\ 2313}#) + #f) + (apply (lambda (#{_\ 2317}# #{id\ 2318}# #{val\ 2319}#) + (let ((#{val\ 2320}# + (#{chi\ 1333}# + #{val\ 2319}# + #{r\ 2308}# + #{w\ 2309}# + #{mod\ 2311}#)) + (#{n\ 2321}# + (#{id-var-name\ 1319}# + #{id\ 2318}# + #{w\ 2309}#))) + (let ((#{b\ 2322}# + (#{lookup\ 1294}# + #{n\ 2321}# + #{r\ 2308}# + #{mod\ 2311}#))) + (let ((#{atom-key\ 2323}# + (#{binding-type\ 1289}# #{b\ 2322}#))) + (if (memv #{atom-key\ 2323}# + '(lexical)) + (#{build-lexical-assignment\ 1267}# + #{s\ 2310}# + (syntax->datum #{id\ 2318}#) + (#{binding-value\ 1290}# #{b\ 2322}#) + #{val\ 2320}#) + (if (memv #{atom-key\ 2323}# + '(global)) + (#{build-global-assignment\ 1270}# + #{s\ 2310}# + #{n\ 2321}# + #{val\ 2320}# + #{mod\ 2311}#) + (if (memv #{atom-key\ 2323}# + '(displaced-lexical)) + (syntax-violation + 'set! + "identifier out of context" + (#{wrap\ 1325}# + #{id\ 2318}# + #{w\ 2309}# + #{mod\ 2311}#)) + (syntax-violation + 'set! + "bad set!" + (#{source-wrap\ 1326}# + #{e\ 2307}# + #{w\ 2309}# + #{s\ 2310}# + #{mod\ 2311}#))))))))) + #{tmp\ 2313}#) + ((lambda (#{tmp\ 2324}#) + (if #{tmp\ 2324}# + (apply (lambda (#{_\ 2325}# + #{head\ 2326}# + #{tail\ 2327}# + #{val\ 2328}#) + (call-with-values + (lambda () + (#{syntax-type\ 1331}# + #{head\ 2326}# + #{r\ 2308}# + '(()) + #f + #f + #{mod\ 2311}# + #t)) + (lambda (#{type\ 2329}# + #{value\ 2330}# + #{ee\ 2331}# + #{ww\ 2332}# + #{ss\ 2333}# + #{modmod\ 2334}#) + (if (memv #{type\ 2329}# + '(module-ref)) + (let ((#{val\ 2335}# + (#{chi\ 1333}# + #{val\ 2328}# + #{r\ 2308}# + #{w\ 2309}# + #{mod\ 2311}#))) + (call-with-values + (lambda () + (#{value\ 2330}# + (cons #{head\ 2326}# + #{tail\ 2327}#))) + (lambda (#{id\ 2337}# #{mod\ 2338}#) + (#{build-global-assignment\ 1270}# + #{s\ 2310}# + #{id\ 2337}# + #{val\ 2335}# + #{mod\ 2338}#)))) + (#{build-application\ 1264}# + #{s\ 2310}# + (#{chi\ 1333}# + (list '#(syntax-object + setter + ((top) + #(ribcage () () ()) + #(ribcage () () ()) + #(ribcage + #(type + value + ee + ww + ss + modmod) + #((top) + (top) + (top) + (top) + (top) + (top)) + #("i" + "i" + "i" + "i" + "i" + "i")) + #(ribcage + #(_ head tail val) + #((top) + (top) + (top) + (top)) + #("i" "i" "i" "i")) + #(ribcage () () ()) + #(ribcage + #(e r w s mod) + #((top) + (top) + (top) + (top) + (top)) + #("i" "i" "i" "i" "i")) + #(ribcage + (lambda-var-list + gen-var + strip + ellipsis? + chi-void + eval-local-transformer + chi-local-syntax + chi-lambda-clause + chi-body + chi-macro + chi-application + chi-expr + chi + chi-top + syntax-type + chi-when-list + chi-install-global + chi-top-sequence + chi-sequence + source-wrap + wrap + bound-id-member? + distinct-bound-ids? + valid-bound-ids? + bound-id=? + free-id=? + id-var-name + same-marks? + join-marks + join-wraps + smart-append + make-binding-wrap + extend-ribcage! + make-empty-ribcage + new-mark + anti-mark + the-anti-mark + top-marked? + top-wrap + empty-wrap + set-ribcage-labels! + set-ribcage-marks! + set-ribcage-symnames! + ribcage-labels + ribcage-marks + ribcage-symnames + ribcage? + make-ribcage + gen-labels + gen-label + make-rename + rename-marks + rename-new + rename-old + subst-rename? + wrap-subst + wrap-marks + make-wrap + id-sym-name&marks + id-sym-name + id? + nonsymbol-id? + global-extend + lookup + macros-only-env + extend-var-env + extend-env + null-env + binding-value + binding-type + make-binding + arg-check + source-annotation + no-source + set-syntax-object-module! + set-syntax-object-wrap! + set-syntax-object-expression! + syntax-object-module + syntax-object-wrap + syntax-object-expression + syntax-object? + make-syntax-object + build-lexical-var + build-letrec + build-named-let + build-let + build-sequence + build-data + build-primref + build-lambda + build-global-definition + maybe-name-value! + build-global-assignment + build-global-reference + analyze-variable + build-lexical-assignment + build-lexical-reference + build-conditional + build-application + build-void + decorate-source + get-global-definition-hook + put-global-definition-hook + gensym-hook + local-eval-hook + top-level-eval-hook + fx< + fx= + fx- + fx+ + *mode* + noexpand) + ((top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top)) + ("i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i")) + #(ribcage + (define-structure + and-map*) + ((top) (top)) + ("i" "i"))) + (hygiene guile)) + #{head\ 2326}#) + #{r\ 2308}# + #{w\ 2309}# + #{mod\ 2311}#) + (map (lambda (#{e\ 2339}#) + (#{chi\ 1333}# + #{e\ 2339}# + #{r\ 2308}# + #{w\ 2309}# + #{mod\ 2311}#)) + (append + #{tail\ 2327}# + (list #{val\ 2328}#)))))))) + #{tmp\ 2324}#) + ((lambda (#{_\ 2341}#) + (syntax-violation + 'set! + "bad set!" + (#{source-wrap\ 1326}# + #{e\ 2307}# + #{w\ 2309}# + #{s\ 2310}# + #{mod\ 2311}#))) + #{tmp\ 2312}#))) + ($sc-dispatch + #{tmp\ 2312}# + '(any (any . each-any) any))))) + ($sc-dispatch + #{tmp\ 2312}# + '(any any any)))) + #{e\ 2307}#))) + (#{global-extend\ 1295}# + 'module-ref + '@ + (lambda (#{e\ 2342}#) + ((lambda (#{tmp\ 2343}#) + ((lambda (#{tmp\ 2344}#) + (if (if #{tmp\ 2344}# + (apply (lambda (#{_\ 2345}# #{mod\ 2346}# #{id\ 2347}#) + (if (and-map #{id?\ 1297}# #{mod\ 2346}#) + (#{id?\ 1297}# #{id\ 2347}#) + #f)) + #{tmp\ 2344}#) + #f) + (apply (lambda (#{_\ 2349}# #{mod\ 2350}# #{id\ 2351}#) + (values + (syntax->datum #{id\ 2351}#) + (syntax->datum + (cons '#(syntax-object + public + ((top) + #(ribcage + #(_ mod id) + #((top) (top) (top)) + #("i" "i" "i")) + #(ribcage () () ()) + #(ribcage #(e) #((top)) #("i")) + #(ribcage + (lambda-var-list + gen-var + strip + ellipsis? + chi-void + eval-local-transformer + chi-local-syntax + chi-lambda-clause + chi-body + chi-macro + chi-application + chi-expr + chi + chi-top + syntax-type + chi-when-list + chi-install-global + chi-top-sequence + chi-sequence + source-wrap + wrap + bound-id-member? + distinct-bound-ids? + valid-bound-ids? + bound-id=? + free-id=? + id-var-name + same-marks? + join-marks + join-wraps + smart-append + make-binding-wrap + extend-ribcage! + make-empty-ribcage + new-mark + anti-mark + the-anti-mark + top-marked? + top-wrap + empty-wrap + set-ribcage-labels! + set-ribcage-marks! + set-ribcage-symnames! + ribcage-labels + ribcage-marks + ribcage-symnames + ribcage? + make-ribcage + gen-labels + gen-label + make-rename + rename-marks + rename-new + rename-old + subst-rename? + wrap-subst + wrap-marks + make-wrap + id-sym-name&marks + id-sym-name + id? + nonsymbol-id? + global-extend + lookup + macros-only-env + extend-var-env + extend-env + null-env + binding-value + binding-type + make-binding + arg-check + source-annotation + no-source + set-syntax-object-module! + set-syntax-object-wrap! + set-syntax-object-expression! + syntax-object-module + syntax-object-wrap + syntax-object-expression + syntax-object? + make-syntax-object + build-lexical-var + build-letrec + build-named-let + build-let + build-sequence + build-data + build-primref + build-lambda + build-global-definition + maybe-name-value! + build-global-assignment + build-global-reference + analyze-variable + build-lexical-assignment + build-lexical-reference + build-conditional + build-application + build-void + decorate-source + get-global-definition-hook + put-global-definition-hook + gensym-hook + local-eval-hook + top-level-eval-hook + fx< + fx= + fx- + fx+ + *mode* + noexpand) + ((top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top)) + ("i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i")) + #(ribcage + (define-structure and-map*) + ((top) (top)) + ("i" "i"))) + (hygiene guile)) + #{mod\ 2350}#)))) + #{tmp\ 2344}#) + (syntax-violation + #f + "source expression failed to match any pattern" + #{tmp\ 2343}#))) + ($sc-dispatch + #{tmp\ 2343}# + '(any each-any any)))) + #{e\ 2342}#))) + (#{global-extend\ 1295}# + 'module-ref + '@@ + (lambda (#{e\ 2353}#) + ((lambda (#{tmp\ 2354}#) + ((lambda (#{tmp\ 2355}#) + (if (if #{tmp\ 2355}# + (apply (lambda (#{_\ 2356}# #{mod\ 2357}# #{id\ 2358}#) + (if (and-map #{id?\ 1297}# #{mod\ 2357}#) + (#{id?\ 1297}# #{id\ 2358}#) + #f)) + #{tmp\ 2355}#) + #f) + (apply (lambda (#{_\ 2360}# #{mod\ 2361}# #{id\ 2362}#) + (values + (syntax->datum #{id\ 2362}#) + (syntax->datum + (cons '#(syntax-object + private + ((top) + #(ribcage + #(_ mod id) + #((top) (top) (top)) + #("i" "i" "i")) + #(ribcage () () ()) + #(ribcage #(e) #((top)) #("i")) + #(ribcage + (lambda-var-list + gen-var + strip + ellipsis? + chi-void + eval-local-transformer + chi-local-syntax + chi-lambda-clause + chi-body + chi-macro + chi-application + chi-expr + chi + chi-top + syntax-type + chi-when-list + chi-install-global + chi-top-sequence + chi-sequence + source-wrap + wrap + bound-id-member? + distinct-bound-ids? + valid-bound-ids? + bound-id=? + free-id=? + id-var-name + same-marks? + join-marks + join-wraps + smart-append + make-binding-wrap + extend-ribcage! + make-empty-ribcage + new-mark + anti-mark + the-anti-mark + top-marked? + top-wrap + empty-wrap + set-ribcage-labels! + set-ribcage-marks! + set-ribcage-symnames! + ribcage-labels + ribcage-marks + ribcage-symnames + ribcage? + make-ribcage + gen-labels + gen-label + make-rename + rename-marks + rename-new + rename-old + subst-rename? + wrap-subst + wrap-marks + make-wrap + id-sym-name&marks + id-sym-name + id? + nonsymbol-id? + global-extend + lookup + macros-only-env + extend-var-env + extend-env + null-env + binding-value + binding-type + make-binding + arg-check + source-annotation + no-source + set-syntax-object-module! + set-syntax-object-wrap! + set-syntax-object-expression! + syntax-object-module + syntax-object-wrap + syntax-object-expression + syntax-object? + make-syntax-object + build-lexical-var + build-letrec + build-named-let + build-let + build-sequence + build-data + build-primref + build-lambda + build-global-definition + maybe-name-value! + build-global-assignment + build-global-reference + analyze-variable + build-lexical-assignment + build-lexical-reference + build-conditional + build-application + build-void + decorate-source + get-global-definition-hook + put-global-definition-hook + gensym-hook + local-eval-hook + top-level-eval-hook + fx< + fx= + fx- + fx+ + *mode* + noexpand) + ((top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top)) + ("i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i")) + #(ribcage + (define-structure and-map*) + ((top) (top)) + ("i" "i"))) + (hygiene guile)) + #{mod\ 2361}#)))) + #{tmp\ 2355}#) + (syntax-violation + #f + "source expression failed to match any pattern" + #{tmp\ 2354}#))) + ($sc-dispatch + #{tmp\ 2354}# + '(any each-any any)))) + #{e\ 2353}#))) + (#{global-extend\ 1295}# + 'core + 'if + (lambda (#{e\ 2364}# + #{r\ 2365}# + #{w\ 2366}# + #{s\ 2367}# + #{mod\ 2368}#) + ((lambda (#{tmp\ 2369}#) + ((lambda (#{tmp\ 2370}#) + (if #{tmp\ 2370}# + (apply (lambda (#{_\ 2371}# #{test\ 2372}# #{then\ 2373}#) + (#{build-conditional\ 1265}# + #{s\ 2367}# + (#{chi\ 1333}# + #{test\ 2372}# + #{r\ 2365}# + #{w\ 2366}# + #{mod\ 2368}#) + (#{chi\ 1333}# + #{then\ 2373}# + #{r\ 2365}# + #{w\ 2366}# + #{mod\ 2368}#) + (#{build-void\ 1263}# #f))) + #{tmp\ 2370}#) + ((lambda (#{tmp\ 2374}#) + (if #{tmp\ 2374}# + (apply (lambda (#{_\ 2375}# + #{test\ 2376}# + #{then\ 2377}# + #{else\ 2378}#) + (#{build-conditional\ 1265}# + #{s\ 2367}# + (#{chi\ 1333}# + #{test\ 2376}# + #{r\ 2365}# + #{w\ 2366}# + #{mod\ 2368}#) + (#{chi\ 1333}# + #{then\ 2377}# + #{r\ 2365}# + #{w\ 2366}# + #{mod\ 2368}#) + (#{chi\ 1333}# + #{else\ 2378}# + #{r\ 2365}# + #{w\ 2366}# + #{mod\ 2368}#))) + #{tmp\ 2374}#) + (syntax-violation + #f + "source expression failed to match any pattern" + #{tmp\ 2369}#))) + ($sc-dispatch + #{tmp\ 2369}# + '(any any any any))))) + ($sc-dispatch + #{tmp\ 2369}# + '(any any any)))) + #{e\ 2364}#))) + (#{global-extend\ 1295}# + 'begin + 'begin + '()) + (#{global-extend\ 1295}# + 'define + 'define + '()) + (#{global-extend\ 1295}# + 'define-syntax + 'define-syntax + '()) + (#{global-extend\ 1295}# + 'eval-when + 'eval-when + '()) + (#{global-extend\ 1295}# + 'core + 'syntax-case + (letrec ((#{gen-syntax-case\ 2382}# + (lambda (#{x\ 2383}# + #{keys\ 2384}# + #{clauses\ 2385}# + #{r\ 2386}# + #{mod\ 2387}#) + (if (null? #{clauses\ 2385}#) + (#{build-application\ 1264}# + #f + (#{build-primref\ 1274}# + #f + 'syntax-violation) + (list (#{build-data\ 1275}# #f #f) + (#{build-data\ 1275}# + #f + "source expression failed to match any pattern") + #{x\ 2383}#)) + ((lambda (#{tmp\ 2388}#) + ((lambda (#{tmp\ 2389}#) + (if #{tmp\ 2389}# + (apply (lambda (#{pat\ 2390}# #{exp\ 2391}#) + (if (if (#{id?\ 1297}# #{pat\ 2390}#) + (and-map + (lambda (#{x\ 2392}#) + (not (#{free-id=?\ 1320}# + #{pat\ 2390}# + #{x\ 2392}#))) + (cons '#(syntax-object + ... + ((top) + #(ribcage + #(pat exp) + #((top) (top)) + #("i" "i")) + #(ribcage () () ()) + #(ribcage + #(x + keys + clauses + r + mod) + #((top) + (top) + (top) + (top) + (top)) + #("i" + "i" + "i" + "i" + "i")) + #(ribcage + (gen-syntax-case + gen-clause + build-dispatch-call + convert-pattern) + ((top) + (top) + (top) + (top)) + ("i" "i" "i" "i")) + #(ribcage + (lambda-var-list + gen-var + strip + ellipsis? + chi-void + eval-local-transformer + chi-local-syntax + chi-lambda-clause + chi-body + chi-macro + chi-application + chi-expr + chi + chi-top + syntax-type + chi-when-list + chi-install-global + chi-top-sequence + chi-sequence + source-wrap + wrap + bound-id-member? + distinct-bound-ids? + valid-bound-ids? + bound-id=? + free-id=? + id-var-name + same-marks? + join-marks + join-wraps + smart-append + make-binding-wrap + extend-ribcage! + make-empty-ribcage + new-mark + anti-mark + the-anti-mark + top-marked? + top-wrap + empty-wrap + set-ribcage-labels! + set-ribcage-marks! + set-ribcage-symnames! + ribcage-labels + ribcage-marks + ribcage-symnames + ribcage? + make-ribcage + gen-labels + gen-label + make-rename + rename-marks + rename-new + rename-old + subst-rename? + wrap-subst + wrap-marks + make-wrap + id-sym-name&marks + id-sym-name + id? + nonsymbol-id? + global-extend + lookup + macros-only-env + extend-var-env + extend-env + null-env + binding-value + binding-type + make-binding + arg-check + source-annotation + no-source + set-syntax-object-module! + set-syntax-object-wrap! + set-syntax-object-expression! + syntax-object-module + syntax-object-wrap + syntax-object-expression + syntax-object? + make-syntax-object + build-lexical-var + build-letrec + build-named-let + build-let + build-sequence + build-data + build-primref + build-lambda + build-global-definition + maybe-name-value! + build-global-assignment + build-global-reference + analyze-variable + build-lexical-assignment + build-lexical-reference + build-conditional + build-application + build-void + decorate-source + get-global-definition-hook + put-global-definition-hook + gensym-hook + local-eval-hook + top-level-eval-hook + fx< + fx= + fx- + fx+ + *mode* + noexpand) + ((top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top) + (top)) + ("i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i" + "i")) + #(ribcage + (define-structure + and-map*) + ((top) (top)) + ("i" "i"))) + (hygiene guile)) + #{keys\ 2384}#)) + #f) + (let ((#{labels\ 2393}# + (list (#{gen-label\ 1302}#))) + (#{var\ 2394}# + (#{gen-var\ 1344}# + #{pat\ 2390}#))) + (#{build-application\ 1264}# + #f + (#{build-lambda\ 1273}# + #f + (list (syntax->datum + #{pat\ 2390}#)) + (list #{var\ 2394}#) + #f + (#{chi\ 1333}# + #{exp\ 2391}# + (#{extend-env\ 1291}# + #{labels\ 2393}# + (list (cons 'syntax + (cons #{var\ 2394}# + 0))) + #{r\ 2386}#) + (#{make-binding-wrap\ 1314}# + (list #{pat\ 2390}#) + #{labels\ 2393}# + '(())) + #{mod\ 2387}#)) + (list #{x\ 2383}#))) + (#{gen-clause\ 2381}# + #{x\ 2383}# + #{keys\ 2384}# + (cdr #{clauses\ 2385}#) + #{r\ 2386}# + #{pat\ 2390}# + #t + #{exp\ 2391}# + #{mod\ 2387}#))) + #{tmp\ 2389}#) + ((lambda (#{tmp\ 2395}#) + (if #{tmp\ 2395}# + (apply (lambda (#{pat\ 2396}# + #{fender\ 2397}# + #{exp\ 2398}#) + (#{gen-clause\ 2381}# + #{x\ 2383}# + #{keys\ 2384}# + (cdr #{clauses\ 2385}#) + #{r\ 2386}# + #{pat\ 2396}# + #{fender\ 2397}# + #{exp\ 2398}# + #{mod\ 2387}#)) + #{tmp\ 2395}#) + ((lambda (#{_\ 2399}#) + (syntax-violation + 'syntax-case + "invalid clause" + (car #{clauses\ 2385}#))) + #{tmp\ 2388}#))) + ($sc-dispatch + #{tmp\ 2388}# + '(any any any))))) + ($sc-dispatch #{tmp\ 2388}# (quote (any any))))) + (car #{clauses\ 2385}#))))) + (#{gen-clause\ 2381}# + (lambda (#{x\ 2400}# + #{keys\ 2401}# + #{clauses\ 2402}# + #{r\ 2403}# + #{pat\ 2404}# + #{fender\ 2405}# + #{exp\ 2406}# + #{mod\ 2407}#) + (call-with-values + (lambda () + (#{convert-pattern\ 2379}# + #{pat\ 2404}# + #{keys\ 2401}#)) + (lambda (#{p\ 2408}# #{pvars\ 2409}#) + (if (not (#{distinct-bound-ids?\ 1323}# + (map car #{pvars\ 2409}#))) + (syntax-violation + 'syntax-case + "duplicate pattern variable" + #{pat\ 2404}#) + (if (not (and-map + (lambda (#{x\ 2410}#) + (not (#{ellipsis?\ 1342}# + (car #{x\ 2410}#)))) + #{pvars\ 2409}#)) + (syntax-violation + 'syntax-case + "misplaced ellipsis" + #{pat\ 2404}#) + (let ((#{y\ 2411}# + (#{gen-var\ 1344}# (quote tmp)))) + (#{build-application\ 1264}# + #f + (#{build-lambda\ 1273}# + #f + (list (quote tmp)) + (list #{y\ 2411}#) + #f + (let ((#{y\ 2412}# + (#{build-lexical-reference\ 1266}# + 'value + #f + 'tmp + #{y\ 2411}#))) + (#{build-conditional\ 1265}# + #f + ((lambda (#{tmp\ 2413}#) + ((lambda (#{tmp\ 2414}#) + (if #{tmp\ 2414}# + (apply (lambda () #{y\ 2412}#) + #{tmp\ 2414}#) + ((lambda (#{_\ 2415}#) + (#{build-conditional\ 1265}# + #f + #{y\ 2412}# + (#{build-dispatch-call\ 2380}# + #{pvars\ 2409}# + #{fender\ 2405}# + #{y\ 2412}# + #{r\ 2403}# + #{mod\ 2407}#) + (#{build-data\ 1275}# + #f + #f))) + #{tmp\ 2413}#))) + ($sc-dispatch + #{tmp\ 2413}# + '#(atom #t)))) + #{fender\ 2405}#) + (#{build-dispatch-call\ 2380}# + #{pvars\ 2409}# + #{exp\ 2406}# + #{y\ 2412}# + #{r\ 2403}# + #{mod\ 2407}#) + (#{gen-syntax-case\ 2382}# + #{x\ 2400}# + #{keys\ 2401}# + #{clauses\ 2402}# + #{r\ 2403}# + #{mod\ 2407}#)))) + (list (if (eq? #{p\ 2408}# (quote any)) + (#{build-application\ 1264}# + #f + (#{build-primref\ 1274}# + #f + 'list) + (list #{x\ 2400}#)) + (#{build-application\ 1264}# + #f + (#{build-primref\ 1274}# + #f + '$sc-dispatch) + (list #{x\ 2400}# + (#{build-data\ 1275}# + #f + #{p\ 2408}#))))))))))))) + (#{build-dispatch-call\ 2380}# + (lambda (#{pvars\ 2416}# + #{exp\ 2417}# + #{y\ 2418}# + #{r\ 2419}# + #{mod\ 2420}#) + (let ((#{ids\ 2421}# (map car #{pvars\ 2416}#)) + (#{levels\ 2422}# (map cdr #{pvars\ 2416}#))) + (let ((#{labels\ 2423}# + (#{gen-labels\ 1303}# #{ids\ 2421}#)) + (#{new-vars\ 2424}# + (map #{gen-var\ 1344}# #{ids\ 2421}#))) + (#{build-application\ 1264}# + #f + (#{build-primref\ 1274}# #f (quote apply)) + (list (#{build-lambda\ 1273}# + #f + (map syntax->datum #{ids\ 2421}#) + #{new-vars\ 2424}# + #f + (#{chi\ 1333}# + #{exp\ 2417}# + (#{extend-env\ 1291}# + #{labels\ 2423}# + (map (lambda (#{var\ 2425}# + #{level\ 2426}#) + (cons 'syntax + (cons #{var\ 2425}# + #{level\ 2426}#))) + #{new-vars\ 2424}# + (map cdr #{pvars\ 2416}#)) + #{r\ 2419}#) + (#{make-binding-wrap\ 1314}# + #{ids\ 2421}# + #{labels\ 2423}# + '(())) + #{mod\ 2420}#)) + #{y\ 2418}#)))))) + (#{convert-pattern\ 2379}# + (lambda (#{pattern\ 2427}# #{keys\ 2428}#) + (letrec ((#{cvt\ 2429}# + (lambda (#{p\ 2430}# #{n\ 2431}# #{ids\ 2432}#) + (if (#{id?\ 1297}# #{p\ 2430}#) + (if (#{bound-id-member?\ 1324}# + #{p\ 2430}# + #{keys\ 2428}#) + (values + (vector (quote free-id) #{p\ 2430}#) + #{ids\ 2432}#) + (values + 'any + (cons (cons #{p\ 2430}# #{n\ 2431}#) + #{ids\ 2432}#))) + ((lambda (#{tmp\ 2433}#) + ((lambda (#{tmp\ 2434}#) + (if (if #{tmp\ 2434}# + (apply (lambda (#{x\ 2435}# + #{dots\ 2436}#) + (#{ellipsis?\ 1342}# + #{dots\ 2436}#)) + #{tmp\ 2434}#) + #f) + (apply (lambda (#{x\ 2437}# + #{dots\ 2438}#) + (call-with-values + (lambda () + (#{cvt\ 2429}# + #{x\ 2437}# + (#{fx+\ 1254}# + #{n\ 2431}# + 1) + #{ids\ 2432}#)) + (lambda (#{p\ 2439}# + #{ids\ 2440}#) + (values + (if (eq? #{p\ 2439}# + 'any) + 'each-any + (vector + 'each + #{p\ 2439}#)) + #{ids\ 2440}#)))) + #{tmp\ 2434}#) + ((lambda (#{tmp\ 2441}#) + (if #{tmp\ 2441}# + (apply (lambda (#{x\ 2442}# + #{y\ 2443}#) + (call-with-values + (lambda () + (#{cvt\ 2429}# + #{y\ 2443}# + #{n\ 2431}# + #{ids\ 2432}#)) + (lambda (#{y\ 2444}# + #{ids\ 2445}#) + (call-with-values + (lambda () + (#{cvt\ 2429}# + #{x\ 2442}# + #{n\ 2431}# + #{ids\ 2445}#)) + (lambda (#{x\ 2446}# + #{ids\ 2447}#) + (values + (cons #{x\ 2446}# + #{y\ 2444}#) + #{ids\ 2447}#)))))) + #{tmp\ 2441}#) + ((lambda (#{tmp\ 2448}#) + (if #{tmp\ 2448}# + (apply (lambda () + (values + '() + #{ids\ 2432}#)) + #{tmp\ 2448}#) + ((lambda (#{tmp\ 2449}#) + (if #{tmp\ 2449}# + (apply (lambda (#{x\ 2450}#) + (call-with-values + (lambda () + (#{cvt\ 2429}# + #{x\ 2450}# + #{n\ 2431}# + #{ids\ 2432}#)) + (lambda (#{p\ 2452}# + #{ids\ 2453}#) + (values + (vector + 'vector + #{p\ 2452}#) + #{ids\ 2453}#)))) + #{tmp\ 2449}#) + ((lambda (#{x\ 2454}#) + (values + (vector + 'atom + (#{strip\ 1343}# + #{p\ 2430}# + '(()))) + #{ids\ 2432}#)) + #{tmp\ 2433}#))) + ($sc-dispatch + #{tmp\ 2433}# + '#(vector + each-any))))) + ($sc-dispatch + #{tmp\ 2433}# + '())))) + ($sc-dispatch + #{tmp\ 2433}# + '(any . any))))) + ($sc-dispatch + #{tmp\ 2433}# + '(any any)))) + #{p\ 2430}#))))) + (#{cvt\ 2429}# #{pattern\ 2427}# 0 (quote ())))))) + (lambda (#{e\ 2455}# + #{r\ 2456}# + #{w\ 2457}# + #{s\ 2458}# + #{mod\ 2459}#) + (let ((#{e\ 2460}# + (#{source-wrap\ 1326}# + #{e\ 2455}# + #{w\ 2457}# + #{s\ 2458}# + #{mod\ 2459}#))) + ((lambda (#{tmp\ 2461}#) + ((lambda (#{tmp\ 2462}#) + (if #{tmp\ 2462}# + (apply (lambda (#{_\ 2463}# + #{val\ 2464}# + #{key\ 2465}# + #{m\ 2466}#) + (if (and-map + (lambda (#{x\ 2467}#) + (if (#{id?\ 1297}# #{x\ 2467}#) + (not (#{ellipsis?\ 1342}# + #{x\ 2467}#)) + #f)) + #{key\ 2465}#) + (let ((#{x\ 2469}# + (#{gen-var\ 1344}# (quote tmp)))) + (#{build-application\ 1264}# + #{s\ 2458}# + (#{build-lambda\ 1273}# + #f + (list (quote tmp)) + (list #{x\ 2469}#) + #f + (#{gen-syntax-case\ 2382}# + (#{build-lexical-reference\ 1266}# + 'value + #f + 'tmp + #{x\ 2469}#) + #{key\ 2465}# + #{m\ 2466}# + #{r\ 2456}# + #{mod\ 2459}#)) + (list (#{chi\ 1333}# + #{val\ 2464}# + #{r\ 2456}# + '(()) + #{mod\ 2459}#)))) + (syntax-violation + 'syntax-case + "invalid literals list" + #{e\ 2460}#))) + #{tmp\ 2462}#) + (syntax-violation + #f + "source expression failed to match any pattern" + #{tmp\ 2461}#))) + ($sc-dispatch + #{tmp\ 2461}# + '(any any each-any . each-any)))) + #{e\ 2460}#))))) + (set! sc-expand + (lambda (#{x\ 2473}# . #{rest\ 2472}#) + (if (if (pair? #{x\ 2473}#) + (equal? (car #{x\ 2473}#) #{noexpand\ 1252}#) + #f) + (cadr #{x\ 2473}#) + (let ((#{m\ 2474}# + (if (null? #{rest\ 2472}#) + 'e + (car #{rest\ 2472}#))) + (#{esew\ 2475}# + (if (let ((#{t\ 2476}# (null? #{rest\ 2472}#))) + (if #{t\ 2476}# + #{t\ 2476}# + (null? (cdr #{rest\ 2472}#)))) + '(eval) + (cadr #{rest\ 2472}#)))) + (with-fluid* + #{*mode*\ 1253}# + #{m\ 2474}# + (lambda () + (#{chi-top\ 1332}# + #{x\ 2473}# + '() + '((top)) + #{m\ 2474}# + #{esew\ 2475}# + (cons 'hygiene + (module-name (current-module)))))))))) + (set! identifier? + (lambda (#{x\ 2477}#) + (#{nonsymbol-id?\ 1296}# #{x\ 2477}#))) + (set! datum->syntax + (lambda (#{id\ 2478}# #{datum\ 2479}#) + (#{make-syntax-object\ 1280}# + #{datum\ 2479}# + (#{syntax-object-wrap\ 1283}# #{id\ 2478}#) + #f))) + (set! syntax->datum + (lambda (#{x\ 2480}#) + (#{strip\ 1343}# #{x\ 2480}# (quote (()))))) + (set! generate-temporaries + (lambda (#{ls\ 2481}#) + (begin + (let ((#{x\ 2482}# #{ls\ 2481}#)) + (if (not (list? #{x\ 2482}#)) + (syntax-violation + 'generate-temporaries + "invalid argument" + #{x\ 2482}#))) + (map (lambda (#{x\ 2483}#) + (#{wrap\ 1325}# (gensym) (quote ((top))) #f)) + #{ls\ 2481}#)))) + (set! free-identifier=? + (lambda (#{x\ 2484}# #{y\ 2485}#) + (begin + (let ((#{x\ 2486}# #{x\ 2484}#)) + (if (not (#{nonsymbol-id?\ 1296}# #{x\ 2486}#)) + (syntax-violation + 'free-identifier=? + "invalid argument" + #{x\ 2486}#))) + (let ((#{x\ 2487}# #{y\ 2485}#)) + (if (not (#{nonsymbol-id?\ 1296}# #{x\ 2487}#)) + (syntax-violation + 'free-identifier=? + "invalid argument" + #{x\ 2487}#))) + (#{free-id=?\ 1320}# #{x\ 2484}# #{y\ 2485}#)))) + (set! bound-identifier=? + (lambda (#{x\ 2488}# #{y\ 2489}#) + (begin + (let ((#{x\ 2490}# #{x\ 2488}#)) + (if (not (#{nonsymbol-id?\ 1296}# #{x\ 2490}#)) + (syntax-violation + 'bound-identifier=? + "invalid argument" + #{x\ 2490}#))) + (let ((#{x\ 2491}# #{y\ 2489}#)) + (if (not (#{nonsymbol-id?\ 1296}# #{x\ 2491}#)) + (syntax-violation + 'bound-identifier=? + "invalid argument" + #{x\ 2491}#))) + (#{bound-id=?\ 1321}# #{x\ 2488}# #{y\ 2489}#)))) + (set! syntax-violation + (lambda (#{who\ 2495}# + #{message\ 2494}# + #{form\ 2493}# + . + #{subform\ 2492}#) + (begin + (let ((#{x\ 2496}# #{who\ 2495}#)) + (if (not ((lambda (#{x\ 2497}#) + (let ((#{t\ 2498}# (not #{x\ 2497}#))) + (if #{t\ 2498}# + #{t\ 2498}# + (let ((#{t\ 2499}# (string? #{x\ 2497}#))) + (if #{t\ 2499}# + #{t\ 2499}# + (symbol? #{x\ 2497}#)))))) + #{x\ 2496}#)) + (syntax-violation + 'syntax-violation + "invalid argument" + #{x\ 2496}#))) + (let ((#{x\ 2500}# #{message\ 2494}#)) + (if (not (string? #{x\ 2500}#)) + (syntax-violation + 'syntax-violation + "invalid argument" + #{x\ 2500}#))) + (scm-error + 'syntax-error + 'sc-expand + (string-append + (if #{who\ 2495}# "~a: " "") + "~a " + (if (null? #{subform\ 2492}#) + "in ~a" + "in subform `~s' of `~s'")) + (let ((#{tail\ 2501}# + (cons #{message\ 2494}# + (map (lambda (#{x\ 2502}#) + (#{strip\ 1343}# #{x\ 2502}# (quote (())))) + (append + #{subform\ 2492}# + (list #{form\ 2493}#)))))) + (if #{who\ 2495}# + (cons #{who\ 2495}# #{tail\ 2501}#) + #{tail\ 2501}#)) + #f)))) + (letrec ((#{match\ 2507}# + (lambda (#{e\ 2508}# + #{p\ 2509}# + #{w\ 2510}# + #{r\ 2511}# + #{mod\ 2512}#) + (if (not #{r\ 2511}#) + #f + (if (eq? #{p\ 2509}# (quote any)) + (cons (#{wrap\ 1325}# + #{e\ 2508}# + #{w\ 2510}# + #{mod\ 2512}#) + #{r\ 2511}#) + (if (#{syntax-object?\ 1281}# #{e\ 2508}#) + (#{match*\ 2506}# + (#{syntax-object-expression\ 1282}# #{e\ 2508}#) + #{p\ 2509}# + (#{join-wraps\ 1316}# + #{w\ 2510}# + (#{syntax-object-wrap\ 1283}# #{e\ 2508}#)) + #{r\ 2511}# + (#{syntax-object-module\ 1284}# #{e\ 2508}#)) + (#{match*\ 2506}# + #{e\ 2508}# + #{p\ 2509}# + #{w\ 2510}# + #{r\ 2511}# + #{mod\ 2512}#)))))) + (#{match*\ 2506}# + (lambda (#{e\ 2513}# + #{p\ 2514}# + #{w\ 2515}# + #{r\ 2516}# + #{mod\ 2517}#) + (if (null? #{p\ 2514}#) + (if (null? #{e\ 2513}#) #{r\ 2516}# #f) + (if (pair? #{p\ 2514}#) + (if (pair? #{e\ 2513}#) + (#{match\ 2507}# + (car #{e\ 2513}#) + (car #{p\ 2514}#) + #{w\ 2515}# + (#{match\ 2507}# + (cdr #{e\ 2513}#) + (cdr #{p\ 2514}#) + #{w\ 2515}# + #{r\ 2516}# + #{mod\ 2517}#) + #{mod\ 2517}#) + #f) + (if (eq? #{p\ 2514}# (quote each-any)) + (let ((#{l\ 2518}# + (#{match-each-any\ 2504}# + #{e\ 2513}# + #{w\ 2515}# + #{mod\ 2517}#))) + (if #{l\ 2518}# + (cons #{l\ 2518}# #{r\ 2516}#) + #f)) + (let ((#{atom-key\ 2519}# (vector-ref #{p\ 2514}# 0))) + (if (memv #{atom-key\ 2519}# (quote (each))) + (if (null? #{e\ 2513}#) + (#{match-empty\ 2505}# + (vector-ref #{p\ 2514}# 1) + #{r\ 2516}#) + (let ((#{l\ 2520}# + (#{match-each\ 2503}# + #{e\ 2513}# + (vector-ref #{p\ 2514}# 1) + #{w\ 2515}# + #{mod\ 2517}#))) + (if #{l\ 2520}# + (letrec ((#{collect\ 2521}# + (lambda (#{l\ 2522}#) + (if (null? (car #{l\ 2522}#)) + #{r\ 2516}# + (cons (map car #{l\ 2522}#) + (#{collect\ 2521}# + (map cdr + #{l\ 2522}#))))))) + (#{collect\ 2521}# #{l\ 2520}#)) + #f))) + (if (memv #{atom-key\ 2519}# (quote (free-id))) + (if (#{id?\ 1297}# #{e\ 2513}#) + (if (#{free-id=?\ 1320}# + (#{wrap\ 1325}# + #{e\ 2513}# + #{w\ 2515}# + #{mod\ 2517}#) + (vector-ref #{p\ 2514}# 1)) + #{r\ 2516}# + #f) + #f) + (if (memv #{atom-key\ 2519}# (quote (atom))) + (if (equal? + (vector-ref #{p\ 2514}# 1) + (#{strip\ 1343}# + #{e\ 2513}# + #{w\ 2515}#)) + #{r\ 2516}# + #f) + (if (memv #{atom-key\ 2519}# (quote (vector))) + (if (vector? #{e\ 2513}#) + (#{match\ 2507}# + (vector->list #{e\ 2513}#) + (vector-ref #{p\ 2514}# 1) + #{w\ 2515}# + #{r\ 2516}# + #{mod\ 2517}#) + #f))))))))))) + (#{match-empty\ 2505}# + (lambda (#{p\ 2523}# #{r\ 2524}#) + (if (null? #{p\ 2523}#) + #{r\ 2524}# + (if (eq? #{p\ 2523}# (quote any)) + (cons (quote ()) #{r\ 2524}#) + (if (pair? #{p\ 2523}#) + (#{match-empty\ 2505}# + (car #{p\ 2523}#) + (#{match-empty\ 2505}# + (cdr #{p\ 2523}#) + #{r\ 2524}#)) + (if (eq? #{p\ 2523}# (quote each-any)) + (cons (quote ()) #{r\ 2524}#) + (let ((#{atom-key\ 2525}# + (vector-ref #{p\ 2523}# 0))) + (if (memv #{atom-key\ 2525}# (quote (each))) + (#{match-empty\ 2505}# + (vector-ref #{p\ 2523}# 1) + #{r\ 2524}#) + (if (memv #{atom-key\ 2525}# + '(free-id atom)) + #{r\ 2524}# + (if (memv #{atom-key\ 2525}# (quote (vector))) + (#{match-empty\ 2505}# + (vector-ref #{p\ 2523}# 1) + #{r\ 2524}#))))))))))) + (#{match-each-any\ 2504}# + (lambda (#{e\ 2526}# #{w\ 2527}# #{mod\ 2528}#) + (if (pair? #{e\ 2526}#) + (let ((#{l\ 2529}# + (#{match-each-any\ 2504}# + (cdr #{e\ 2526}#) + #{w\ 2527}# + #{mod\ 2528}#))) + (if #{l\ 2529}# + (cons (#{wrap\ 1325}# + (car #{e\ 2526}#) + #{w\ 2527}# + #{mod\ 2528}#) + #{l\ 2529}#) + #f)) + (if (null? #{e\ 2526}#) + '() + (if (#{syntax-object?\ 1281}# #{e\ 2526}#) + (#{match-each-any\ 2504}# + (#{syntax-object-expression\ 1282}# #{e\ 2526}#) + (#{join-wraps\ 1316}# + #{w\ 2527}# + (#{syntax-object-wrap\ 1283}# #{e\ 2526}#)) + #{mod\ 2528}#) + #f))))) + (#{match-each\ 2503}# + (lambda (#{e\ 2530}# + #{p\ 2531}# + #{w\ 2532}# + #{mod\ 2533}#) + (if (pair? #{e\ 2530}#) + (let ((#{first\ 2534}# + (#{match\ 2507}# + (car #{e\ 2530}#) + #{p\ 2531}# + #{w\ 2532}# + '() + #{mod\ 2533}#))) + (if #{first\ 2534}# + (let ((#{rest\ 2535}# + (#{match-each\ 2503}# + (cdr #{e\ 2530}#) + #{p\ 2531}# + #{w\ 2532}# + #{mod\ 2533}#))) + (if #{rest\ 2535}# + (cons #{first\ 2534}# #{rest\ 2535}#) + #f)) + #f)) + (if (null? #{e\ 2530}#) + '() + (if (#{syntax-object?\ 1281}# #{e\ 2530}#) + (#{match-each\ 2503}# + (#{syntax-object-expression\ 1282}# #{e\ 2530}#) + #{p\ 2531}# + (#{join-wraps\ 1316}# + #{w\ 2532}# + (#{syntax-object-wrap\ 1283}# #{e\ 2530}#)) + (#{syntax-object-module\ 1284}# #{e\ 2530}#)) + #f)))))) + (set! $sc-dispatch + (lambda (#{e\ 2536}# #{p\ 2537}#) + (if (eq? #{p\ 2537}# (quote any)) + (list #{e\ 2536}#) + (if (#{syntax-object?\ 1281}# #{e\ 2536}#) + (#{match*\ 2506}# + (#{syntax-object-expression\ 1282}# #{e\ 2536}#) + #{p\ 2537}# + (#{syntax-object-wrap\ 1283}# #{e\ 2536}#) + '() + (#{syntax-object-module\ 1284}# #{e\ 2536}#)) + (#{match*\ 2506}# + #{e\ 2536}# + #{p\ 2537}# + '(()) + '() + #f))))))))) + +(define with-syntax + (make-syncase-macro + 'macro + (lambda (#{x\ 2538}#) + ((lambda (#{tmp\ 2539}#) + ((lambda (#{tmp\ 2540}#) + (if #{tmp\ 2540}# + (apply (lambda (#{_\ 2541}# #{e1\ 2542}# #{e2\ 2543}#) + (cons '#(syntax-object + begin + ((top) + #(ribcage + #(_ e1 e2) + #((top) (top) (top)) + #("i" "i" "i")) + #(ribcage () () ()) + #(ribcage #(x) #((top)) #("i"))) + (hygiene guile)) + (cons #{e1\ 2542}# #{e2\ 2543}#))) + #{tmp\ 2540}#) + ((lambda (#{tmp\ 2545}#) + (if #{tmp\ 2545}# + (apply (lambda (#{_\ 2546}# + #{out\ 2547}# + #{in\ 2548}# + #{e1\ 2549}# + #{e2\ 2550}#) + (list '#(syntax-object + syntax-case + ((top) + #(ribcage + #(_ out in e1 e2) + #((top) (top) (top) (top) (top)) + #("i" "i" "i" "i" "i")) + #(ribcage () () ()) + #(ribcage #(x) #((top)) #("i"))) + (hygiene guile)) + #{in\ 2548}# + '() + (list #{out\ 2547}# + (cons '#(syntax-object + begin + ((top) + #(ribcage + #(_ out in e1 e2) + #((top) + (top) + (top) + (top) + (top)) + #("i" "i" "i" "i" "i")) + #(ribcage () () ()) + #(ribcage + #(x) + #((top)) + #("i"))) + (hygiene guile)) + (cons #{e1\ 2549}# + #{e2\ 2550}#))))) + #{tmp\ 2545}#) + ((lambda (#{tmp\ 2552}#) + (if #{tmp\ 2552}# + (apply (lambda (#{_\ 2553}# + #{out\ 2554}# + #{in\ 2555}# + #{e1\ 2556}# + #{e2\ 2557}#) + (list '#(syntax-object + syntax-case + ((top) + #(ribcage + #(_ out in e1 e2) + #((top) (top) (top) (top) (top)) + #("i" "i" "i" "i" "i")) + #(ribcage () () ()) + #(ribcage #(x) #((top)) #("i"))) + (hygiene guile)) + (cons '#(syntax-object + list + ((top) + #(ribcage + #(_ out in e1 e2) + #((top) + (top) + (top) + (top) + (top)) + #("i" "i" "i" "i" "i")) + #(ribcage () () ()) + #(ribcage + #(x) + #((top)) + #("i"))) + (hygiene guile)) + #{in\ 2555}#) + '() + (list #{out\ 2554}# + (cons '#(syntax-object + begin + ((top) + #(ribcage + #(_ out in e1 e2) + #((top) + (top) + (top) + (top) + (top)) + #("i" + "i" + "i" + "i" + "i")) + #(ribcage () () ()) + #(ribcage + #(x) + #((top)) + #("i"))) + (hygiene guile)) + (cons #{e1\ 2556}# + #{e2\ 2557}#))))) + #{tmp\ 2552}#) + (syntax-violation + #f + "source expression failed to match any pattern" + #{tmp\ 2539}#))) + ($sc-dispatch + #{tmp\ 2539}# + '(any #(each (any any)) any . each-any))))) + ($sc-dispatch + #{tmp\ 2539}# + '(any ((any any)) any . each-any))))) + ($sc-dispatch + #{tmp\ 2539}# + '(any () any . each-any)))) + #{x\ 2538}#)))) + +(define syntax-rules + (make-syncase-macro + 'macro + (lambda (#{x\ 2561}#) + ((lambda (#{tmp\ 2562}#) + ((lambda (#{tmp\ 2563}#) + (if #{tmp\ 2563}# + (apply (lambda (#{_\ 2564}# + #{k\ 2565}# + #{keyword\ 2566}# + #{pattern\ 2567}# + #{template\ 2568}#) + (list '#(syntax-object + lambda + ((top) + #(ribcage + #(_ k keyword pattern template) + #((top) (top) (top) (top) (top)) + #("i" "i" "i" "i" "i")) + #(ribcage () () ()) + #(ribcage #(x) #((top)) #("i"))) + (hygiene guile)) + '(#(syntax-object + x + ((top) + #(ribcage + #(_ k keyword pattern template) + #((top) (top) (top) (top) (top)) + #("i" "i" "i" "i" "i")) + #(ribcage () () ()) + #(ribcage #(x) #((top)) #("i"))) + (hygiene guile))) + (cons '#(syntax-object + syntax-case + ((top) + #(ribcage + #(_ k keyword pattern template) + #((top) (top) (top) (top) (top)) + #("i" "i" "i" "i" "i")) + #(ribcage () () ()) + #(ribcage #(x) #((top)) #("i"))) + (hygiene guile)) + (cons '#(syntax-object + x + ((top) + #(ribcage + #(_ k keyword pattern template) + #((top) (top) (top) (top) (top)) + #("i" "i" "i" "i" "i")) + #(ribcage () () ()) + #(ribcage #(x) #((top)) #("i"))) + (hygiene guile)) + (cons #{k\ 2565}# + (map (lambda (#{tmp\ 2571}# + #{tmp\ 2570}#) + (list (cons '#(syntax-object + dummy + ((top) + #(ribcage + #(_ + k + keyword + pattern + template) + #((top) + (top) + (top) + (top) + (top)) + #("i" + "i" + "i" + "i" + "i")) + #(ribcage + () + () + ()) + #(ribcage + #(x) + #((top)) + #("i"))) + (hygiene + guile)) + #{tmp\ 2570}#) + (list '#(syntax-object + syntax + ((top) + #(ribcage + #(_ + k + keyword + pattern + template) + #((top) + (top) + (top) + (top) + (top)) + #("i" + "i" + "i" + "i" + "i")) + #(ribcage + () + () + ()) + #(ribcage + #(x) + #((top)) + #("i"))) + (hygiene + guile)) + #{tmp\ 2571}#))) + #{template\ 2568}# + #{pattern\ 2567}#)))))) + #{tmp\ 2563}#) + (syntax-violation + #f + "source expression failed to match any pattern" + #{tmp\ 2562}#))) + ($sc-dispatch + #{tmp\ 2562}# + '(any each-any . #(each ((any . any) any)))))) + #{x\ 2561}#)))) + +(define let* + (make-extended-syncase-macro + (module-ref (current-module) (quote let*)) + 'macro + (lambda (#{x\ 2572}#) + ((lambda (#{tmp\ 2573}#) + ((lambda (#{tmp\ 2574}#) + (if (if #{tmp\ 2574}# + (apply (lambda (#{let*\ 2575}# + #{x\ 2576}# + #{v\ 2577}# + #{e1\ 2578}# + #{e2\ 2579}#) + (and-map identifier? #{x\ 2576}#)) + #{tmp\ 2574}#) + #f) + (apply (lambda (#{let*\ 2581}# + #{x\ 2582}# + #{v\ 2583}# + #{e1\ 2584}# + #{e2\ 2585}#) + (letrec ((#{f\ 2586}# + (lambda (#{bindings\ 2587}#) + (if (null? #{bindings\ 2587}#) + (cons '#(syntax-object + let + ((top) + #(ribcage () () ()) + #(ribcage + #(f bindings) + #((top) (top)) + #("i" "i")) + #(ribcage + #(let* x v e1 e2) + #((top) + (top) + (top) + (top) + (top)) + #("i" "i" "i" "i" "i")) + #(ribcage () () ()) + #(ribcage + #(x) + #((top)) + #("i"))) + (hygiene guile)) + (cons '() + (cons #{e1\ 2584}# + #{e2\ 2585}#))) + ((lambda (#{tmp\ 2591}#) + ((lambda (#{tmp\ 2592}#) + (if #{tmp\ 2592}# + (apply (lambda (#{body\ 2593}# + #{binding\ 2594}#) + (list '#(syntax-object + let + ((top) + #(ribcage + #(body + binding) + #((top) + (top)) + #("i" "i")) + #(ribcage + () + () + ()) + #(ribcage + #(f + bindings) + #((top) + (top)) + #("i" "i")) + #(ribcage + #(let* + x + v + e1 + e2) + #((top) + (top) + (top) + (top) + (top)) + #("i" + "i" + "i" + "i" + "i")) + #(ribcage + () + () + ()) + #(ribcage + #(x) + #((top)) + #("i"))) + (hygiene + guile)) + (list #{binding\ 2594}#) + #{body\ 2593}#)) + #{tmp\ 2592}#) + (syntax-violation + #f + "source expression failed to match any pattern" + #{tmp\ 2591}#))) + ($sc-dispatch + #{tmp\ 2591}# + '(any any)))) + (list (#{f\ 2586}# + (cdr #{bindings\ 2587}#)) + (car #{bindings\ 2587}#))))))) + (#{f\ 2586}# (map list #{x\ 2582}# #{v\ 2583}#)))) + #{tmp\ 2574}#) + (syntax-violation + #f + "source expression failed to match any pattern" + #{tmp\ 2573}#))) + ($sc-dispatch + #{tmp\ 2573}# + '(any #(each (any any)) any . each-any)))) + #{x\ 2572}#)))) + +(define do + (make-extended-syncase-macro + (module-ref (current-module) (quote do)) + 'macro + (lambda (#{orig-x\ 2595}#) + ((lambda (#{tmp\ 2596}#) + ((lambda (#{tmp\ 2597}#) + (if #{tmp\ 2597}# + (apply (lambda (#{_\ 2598}# + #{var\ 2599}# + #{init\ 2600}# + #{step\ 2601}# + #{e0\ 2602}# + #{e1\ 2603}# + #{c\ 2604}#) + ((lambda (#{tmp\ 2605}#) + ((lambda (#{tmp\ 2606}#) + (if #{tmp\ 2606}# + (apply (lambda (#{step\ 2607}#) + ((lambda (#{tmp\ 2608}#) + ((lambda (#{tmp\ 2609}#) + (if #{tmp\ 2609}# + (apply (lambda () + (list '#(syntax-object + let + ((top) + #(ribcage + #(step) + #((top)) + #("i")) + #(ribcage + #(_ + var + init + step + e0 + e1 + c) + #((top) + (top) + (top) + (top) + (top) + (top) + (top)) + #("i" + "i" + "i" + "i" + "i" + "i" + "i")) + #(ribcage + () + () + ()) + #(ribcage + #(orig-x) + #((top)) + #("i"))) + (hygiene + guile)) + '#(syntax-object + doloop + ((top) + #(ribcage + #(step) + #((top)) + #("i")) + #(ribcage + #(_ + var + init + step + e0 + e1 + c) + #((top) + (top) + (top) + (top) + (top) + (top) + (top)) + #("i" + "i" + "i" + "i" + "i" + "i" + "i")) + #(ribcage + () + () + ()) + #(ribcage + #(orig-x) + #((top)) + #("i"))) + (hygiene + guile)) + (map list + #{var\ 2599}# + #{init\ 2600}#) + (list '#(syntax-object + if + ((top) + #(ribcage + #(step) + #((top)) + #("i")) + #(ribcage + #(_ + var + init + step + e0 + e1 + c) + #((top) + (top) + (top) + (top) + (top) + (top) + (top)) + #("i" + "i" + "i" + "i" + "i" + "i" + "i")) + #(ribcage + () + () + ()) + #(ribcage + #(orig-x) + #((top)) + #("i"))) + (hygiene + guile)) + (list '#(syntax-object + not + ((top) + #(ribcage + #(step) + #((top)) + #("i")) + #(ribcage + #(_ + var + init + step + e0 + e1 + c) + #((top) + (top) + (top) + (top) + (top) + (top) + (top)) + #("i" + "i" + "i" + "i" + "i" + "i" + "i")) + #(ribcage + () + () + ()) + #(ribcage + #(orig-x) + #((top)) + #("i"))) + (hygiene + guile)) + #{e0\ 2602}#) + (cons '#(syntax-object + begin + ((top) + #(ribcage + #(step) + #((top)) + #("i")) + #(ribcage + #(_ + var + init + step + e0 + e1 + c) + #((top) + (top) + (top) + (top) + (top) + (top) + (top)) + #("i" + "i" + "i" + "i" + "i" + "i" + "i")) + #(ribcage + () + () + ()) + #(ribcage + #(orig-x) + #((top)) + #("i"))) + (hygiene + guile)) + (append + #{c\ 2604}# + (list (cons '#(syntax-object + doloop + ((top) + #(ribcage + #(step) + #((top)) + #("i")) + #(ribcage + #(_ + var + init + step + e0 + e1 + c) + #((top) + (top) + (top) + (top) + (top) + (top) + (top)) + #("i" + "i" + "i" + "i" + "i" + "i" + "i")) + #(ribcage + () + () + ()) + #(ribcage + #(orig-x) + #((top)) + #("i"))) + (hygiene + guile)) + #{step\ 2607}#))))))) + #{tmp\ 2609}#) + ((lambda (#{tmp\ 2614}#) + (if #{tmp\ 2614}# + (apply (lambda (#{e1\ 2615}# + #{e2\ 2616}#) + (list '#(syntax-object + let + ((top) + #(ribcage + #(e1 + e2) + #((top) + (top)) + #("i" + "i")) + #(ribcage + #(step) + #((top)) + #("i")) + #(ribcage + #(_ + var + init + step + e0 + e1 + c) + #((top) + (top) + (top) + (top) + (top) + (top) + (top)) + #("i" + "i" + "i" + "i" + "i" + "i" + "i")) + #(ribcage + () + () + ()) + #(ribcage + #(orig-x) + #((top)) + #("i"))) + (hygiene + guile)) + '#(syntax-object + doloop + ((top) + #(ribcage + #(e1 + e2) + #((top) + (top)) + #("i" + "i")) + #(ribcage + #(step) + #((top)) + #("i")) + #(ribcage + #(_ + var + init + step + e0 + e1 + c) + #((top) + (top) + (top) + (top) + (top) + (top) + (top)) + #("i" + "i" + "i" + "i" + "i" + "i" + "i")) + #(ribcage + () + () + ()) + #(ribcage + #(orig-x) + #((top)) + #("i"))) + (hygiene + guile)) + (map list + #{var\ 2599}# + #{init\ 2600}#) + (list '#(syntax-object + if + ((top) + #(ribcage + #(e1 + e2) + #((top) + (top)) + #("i" + "i")) + #(ribcage + #(step) + #((top)) + #("i")) + #(ribcage + #(_ + var + init + step + e0 + e1 + c) + #((top) + (top) + (top) + (top) + (top) + (top) + (top)) + #("i" + "i" + "i" + "i" + "i" + "i" + "i")) + #(ribcage + () + () + ()) + #(ribcage + #(orig-x) + #((top)) + #("i"))) + (hygiene + guile)) + #{e0\ 2602}# + (cons '#(syntax-object + begin + ((top) + #(ribcage + #(e1 + e2) + #((top) + (top)) + #("i" + "i")) + #(ribcage + #(step) + #((top)) + #("i")) + #(ribcage + #(_ + var + init + step + e0 + e1 + c) + #((top) + (top) + (top) + (top) + (top) + (top) + (top)) + #("i" + "i" + "i" + "i" + "i" + "i" + "i")) + #(ribcage + () + () + ()) + #(ribcage + #(orig-x) + #((top)) + #("i"))) + (hygiene + guile)) + (cons #{e1\ 2615}# + #{e2\ 2616}#)) + (cons '#(syntax-object + begin + ((top) + #(ribcage + #(e1 + e2) + #((top) + (top)) + #("i" + "i")) + #(ribcage + #(step) + #((top)) + #("i")) + #(ribcage + #(_ + var + init + step + e0 + e1 + c) + #((top) + (top) + (top) + (top) + (top) + (top) + (top)) + #("i" + "i" + "i" + "i" + "i" + "i" + "i")) + #(ribcage + () + () + ()) + #(ribcage + #(orig-x) + #((top)) + #("i"))) + (hygiene + guile)) + (append + #{c\ 2604}# + (list (cons '#(syntax-object + doloop + ((top) + #(ribcage + #(e1 + e2) + #((top) + (top)) + #("i" + "i")) + #(ribcage + #(step) + #((top)) + #("i")) + #(ribcage + #(_ + var + init + step + e0 + e1 + c) + #((top) + (top) + (top) + (top) + (top) + (top) + (top)) + #("i" + "i" + "i" + "i" + "i" + "i" + "i")) + #(ribcage + () + () + ()) + #(ribcage + #(orig-x) + #((top)) + #("i"))) + (hygiene + guile)) + #{step\ 2607}#))))))) + #{tmp\ 2614}#) + (syntax-violation + #f + "source expression failed to match any pattern" + #{tmp\ 2608}#))) + ($sc-dispatch + #{tmp\ 2608}# + '(any . each-any))))) + ($sc-dispatch + #{tmp\ 2608}# + '()))) + #{e1\ 2603}#)) + #{tmp\ 2606}#) + (syntax-violation + #f + "source expression failed to match any pattern" + #{tmp\ 2605}#))) + ($sc-dispatch #{tmp\ 2605}# (quote each-any)))) + (map (lambda (#{v\ 2623}# #{s\ 2624}#) + ((lambda (#{tmp\ 2625}#) + ((lambda (#{tmp\ 2626}#) + (if #{tmp\ 2626}# + (apply (lambda () #{v\ 2623}#) + #{tmp\ 2626}#) + ((lambda (#{tmp\ 2627}#) + (if #{tmp\ 2627}# + (apply (lambda (#{e\ 2628}#) + #{e\ 2628}#) + #{tmp\ 2627}#) + ((lambda (#{_\ 2629}#) + (syntax-violation + 'do + "bad step expression" + #{orig-x\ 2595}# + #{s\ 2624}#)) + #{tmp\ 2625}#))) + ($sc-dispatch + #{tmp\ 2625}# + '(any))))) + ($sc-dispatch #{tmp\ 2625}# (quote ())))) + #{s\ 2624}#)) + #{var\ 2599}# + #{step\ 2601}#))) + #{tmp\ 2597}#) + (syntax-violation + #f + "source expression failed to match any pattern" + #{tmp\ 2596}#))) + ($sc-dispatch + #{tmp\ 2596}# + '(any #(each (any any . any)) + (any . each-any) + . + each-any)))) + #{orig-x\ 2595}#)))) + +(define quasiquote + (make-extended-syncase-macro + (module-ref (current-module) (quote quasiquote)) + 'macro + (letrec ((#{quasicons\ 2632}# + (lambda (#{x\ 2636}# #{y\ 2637}#) + ((lambda (#{tmp\ 2638}#) + ((lambda (#{tmp\ 2639}#) + (if #{tmp\ 2639}# + (apply (lambda (#{x\ 2640}# #{y\ 2641}#) + ((lambda (#{tmp\ 2642}#) + ((lambda (#{tmp\ 2643}#) + (if #{tmp\ 2643}# + (apply (lambda (#{dy\ 2644}#) + ((lambda (#{tmp\ 2645}#) + ((lambda (#{tmp\ 2646}#) + (if #{tmp\ 2646}# + (apply (lambda (#{dx\ 2647}#) + (list '#(syntax-object + quote + ((top) + #(ribcage + #(dx) + #((top)) + #("i")) + #(ribcage + #(dy) + #((top)) + #("i")) + #(ribcage + #(x + y) + #((top) + (top)) + #("i" + "i")) + #(ribcage + () + () + ()) + #(ribcage + () + () + ()) + #(ribcage + #(x + y) + #((top) + (top)) + #("i" + "i")) + #(ribcage + #(quasicons + quasiappend + quasivector + quasi) + #((top) + (top) + (top) + (top)) + #("i" + "i" + "i" + "i"))) + (hygiene + guile)) + (cons #{dx\ 2647}# + #{dy\ 2644}#))) + #{tmp\ 2646}#) + ((lambda (#{_\ 2648}#) + (if (null? #{dy\ 2644}#) + (list '#(syntax-object + list + ((top) + #(ribcage + #(_) + #((top)) + #("i")) + #(ribcage + #(dy) + #((top)) + #("i")) + #(ribcage + #(x + y) + #((top) + (top)) + #("i" + "i")) + #(ribcage + () + () + ()) + #(ribcage + () + () + ()) + #(ribcage + #(x + y) + #((top) + (top)) + #("i" + "i")) + #(ribcage + #(quasicons + quasiappend + quasivector + quasi) + #((top) + (top) + (top) + (top)) + #("i" + "i" + "i" + "i"))) + (hygiene + guile)) + #{x\ 2640}#) + (list '#(syntax-object + cons + ((top) + #(ribcage + #(_) + #((top)) + #("i")) + #(ribcage + #(dy) + #((top)) + #("i")) + #(ribcage + #(x + y) + #((top) + (top)) + #("i" + "i")) + #(ribcage + () + () + ()) + #(ribcage + () + () + ()) + #(ribcage + #(x + y) + #((top) + (top)) + #("i" + "i")) + #(ribcage + #(quasicons + quasiappend + quasivector + quasi) + #((top) + (top) + (top) + (top)) + #("i" + "i" + "i" + "i"))) + (hygiene + guile)) + #{x\ 2640}# + #{y\ 2641}#))) + #{tmp\ 2645}#))) + ($sc-dispatch + #{tmp\ 2645}# + '(#(free-id + #(syntax-object + quote + ((top) + #(ribcage + #(dy) + #((top)) + #("i")) + #(ribcage + #(x y) + #((top) + (top)) + #("i" "i")) + #(ribcage + () + () + ()) + #(ribcage + () + () + ()) + #(ribcage + #(x y) + #((top) + (top)) + #("i" "i")) + #(ribcage + #(quasicons + quasiappend + quasivector + quasi) + #((top) + (top) + (top) + (top)) + #("i" + "i" + "i" + "i"))) + (hygiene + guile))) + any)))) + #{x\ 2640}#)) + #{tmp\ 2643}#) + ((lambda (#{tmp\ 2649}#) + (if #{tmp\ 2649}# + (apply (lambda (#{stuff\ 2650}#) + (cons '#(syntax-object + list + ((top) + #(ribcage + #(stuff) + #((top)) + #("i")) + #(ribcage + #(x y) + #((top) + (top)) + #("i" "i")) + #(ribcage + () + () + ()) + #(ribcage + () + () + ()) + #(ribcage + #(x y) + #((top) + (top)) + #("i" "i")) + #(ribcage + #(quasicons + quasiappend + quasivector + quasi) + #((top) + (top) + (top) + (top)) + #("i" + "i" + "i" + "i"))) + (hygiene + guile)) + (cons #{x\ 2640}# + #{stuff\ 2650}#))) + #{tmp\ 2649}#) + ((lambda (#{else\ 2651}#) + (list '#(syntax-object + cons + ((top) + #(ribcage + #(else) + #((top)) + #("i")) + #(ribcage + #(x y) + #((top) (top)) + #("i" "i")) + #(ribcage () () ()) + #(ribcage () () ()) + #(ribcage + #(x y) + #((top) (top)) + #("i" "i")) + #(ribcage + #(quasicons + quasiappend + quasivector + quasi) + #((top) + (top) + (top) + (top)) + #("i" + "i" + "i" + "i"))) + (hygiene guile)) + #{x\ 2640}# + #{y\ 2641}#)) + #{tmp\ 2642}#))) + ($sc-dispatch + #{tmp\ 2642}# + '(#(free-id + #(syntax-object + list + ((top) + #(ribcage + #(x y) + #((top) (top)) + #("i" "i")) + #(ribcage () () ()) + #(ribcage () () ()) + #(ribcage + #(x y) + #((top) (top)) + #("i" "i")) + #(ribcage + #(quasicons + quasiappend + quasivector + quasi) + #((top) + (top) + (top) + (top)) + #("i" "i" "i" "i"))) + (hygiene guile))) + . + any))))) + ($sc-dispatch + #{tmp\ 2642}# + '(#(free-id + #(syntax-object + quote + ((top) + #(ribcage + #(x y) + #((top) (top)) + #("i" "i")) + #(ribcage () () ()) + #(ribcage () () ()) + #(ribcage + #(x y) + #((top) (top)) + #("i" "i")) + #(ribcage + #(quasicons + quasiappend + quasivector + quasi) + #((top) (top) (top) (top)) + #("i" "i" "i" "i"))) + (hygiene guile))) + any)))) + #{y\ 2641}#)) + #{tmp\ 2639}#) + (syntax-violation + #f + "source expression failed to match any pattern" + #{tmp\ 2638}#))) + ($sc-dispatch #{tmp\ 2638}# (quote (any any))))) + (list #{x\ 2636}# #{y\ 2637}#)))) + (#{quasiappend\ 2633}# + (lambda (#{x\ 2652}# #{y\ 2653}#) + ((lambda (#{tmp\ 2654}#) + ((lambda (#{tmp\ 2655}#) + (if #{tmp\ 2655}# + (apply (lambda (#{x\ 2656}# #{y\ 2657}#) + ((lambda (#{tmp\ 2658}#) + ((lambda (#{tmp\ 2659}#) + (if #{tmp\ 2659}# + (apply (lambda () #{x\ 2656}#) + #{tmp\ 2659}#) + ((lambda (#{_\ 2660}#) + (list '#(syntax-object + append + ((top) + #(ribcage + #(_) + #((top)) + #("i")) + #(ribcage + #(x y) + #((top) (top)) + #("i" "i")) + #(ribcage () () ()) + #(ribcage () () ()) + #(ribcage + #(x y) + #((top) (top)) + #("i" "i")) + #(ribcage + #(quasicons + quasiappend + quasivector + quasi) + #((top) + (top) + (top) + (top)) + #("i" "i" "i" "i"))) + (hygiene guile)) + #{x\ 2656}# + #{y\ 2657}#)) + #{tmp\ 2658}#))) + ($sc-dispatch + #{tmp\ 2658}# + '(#(free-id + #(syntax-object + quote + ((top) + #(ribcage + #(x y) + #((top) (top)) + #("i" "i")) + #(ribcage () () ()) + #(ribcage () () ()) + #(ribcage + #(x y) + #((top) (top)) + #("i" "i")) + #(ribcage + #(quasicons + quasiappend + quasivector + quasi) + #((top) (top) (top) (top)) + #("i" "i" "i" "i"))) + (hygiene guile))) + ())))) + #{y\ 2657}#)) + #{tmp\ 2655}#) + (syntax-violation + #f + "source expression failed to match any pattern" + #{tmp\ 2654}#))) + ($sc-dispatch #{tmp\ 2654}# (quote (any any))))) + (list #{x\ 2652}# #{y\ 2653}#)))) + (#{quasivector\ 2634}# + (lambda (#{x\ 2661}#) + ((lambda (#{tmp\ 2662}#) + ((lambda (#{x\ 2663}#) + ((lambda (#{tmp\ 2664}#) + ((lambda (#{tmp\ 2665}#) + (if #{tmp\ 2665}# + (apply (lambda (#{x\ 2666}#) + (list '#(syntax-object + quote + ((top) + #(ribcage + #(x) + #((top)) + #("i")) + #(ribcage + #(x) + #((top)) + #("i")) + #(ribcage () () ()) + #(ribcage () () ()) + #(ribcage + #(x) + #((top)) + #("i")) + #(ribcage + #(quasicons + quasiappend + quasivector + quasi) + #((top) (top) (top) (top)) + #("i" "i" "i" "i"))) + (hygiene guile)) + (list->vector #{x\ 2666}#))) + #{tmp\ 2665}#) + ((lambda (#{tmp\ 2668}#) + (if #{tmp\ 2668}# + (apply (lambda (#{x\ 2669}#) + (cons '#(syntax-object + vector + ((top) + #(ribcage + #(x) + #((top)) + #("i")) + #(ribcage + #(x) + #((top)) + #("i")) + #(ribcage () () ()) + #(ribcage () () ()) + #(ribcage + #(x) + #((top)) + #("i")) + #(ribcage + #(quasicons + quasiappend + quasivector + quasi) + #((top) + (top) + (top) + (top)) + #("i" "i" "i" "i"))) + (hygiene guile)) + #{x\ 2669}#)) + #{tmp\ 2668}#) + ((lambda (#{_\ 2671}#) + (list '#(syntax-object + list->vector + ((top) + #(ribcage + #(_) + #((top)) + #("i")) + #(ribcage + #(x) + #((top)) + #("i")) + #(ribcage () () ()) + #(ribcage () () ()) + #(ribcage + #(x) + #((top)) + #("i")) + #(ribcage + #(quasicons + quasiappend + quasivector + quasi) + #((top) (top) (top) (top)) + #("i" "i" "i" "i"))) + (hygiene guile)) + #{x\ 2663}#)) + #{tmp\ 2664}#))) + ($sc-dispatch + #{tmp\ 2664}# + '(#(free-id + #(syntax-object + list + ((top) + #(ribcage #(x) #((top)) #("i")) + #(ribcage () () ()) + #(ribcage () () ()) + #(ribcage #(x) #((top)) #("i")) + #(ribcage + #(quasicons + quasiappend + quasivector + quasi) + #((top) (top) (top) (top)) + #("i" "i" "i" "i"))) + (hygiene guile))) + . + each-any))))) + ($sc-dispatch + #{tmp\ 2664}# + '(#(free-id + #(syntax-object + quote + ((top) + #(ribcage #(x) #((top)) #("i")) + #(ribcage () () ()) + #(ribcage () () ()) + #(ribcage #(x) #((top)) #("i")) + #(ribcage + #(quasicons + quasiappend + quasivector + quasi) + #((top) (top) (top) (top)) + #("i" "i" "i" "i"))) + (hygiene guile))) + each-any)))) + #{x\ 2663}#)) + #{tmp\ 2662}#)) + #{x\ 2661}#))) + (#{quasi\ 2635}# + (lambda (#{p\ 2672}# #{lev\ 2673}#) + ((lambda (#{tmp\ 2674}#) + ((lambda (#{tmp\ 2675}#) + (if #{tmp\ 2675}# + (apply (lambda (#{p\ 2676}#) + (if (= #{lev\ 2673}# 0) + #{p\ 2676}# + (#{quasicons\ 2632}# + '(#(syntax-object + quote + ((top) + #(ribcage #(p) #((top)) #("i")) + #(ribcage () () ()) + #(ribcage + #(p lev) + #((top) (top)) + #("i" "i")) + #(ribcage + #(quasicons + quasiappend + quasivector + quasi) + #((top) (top) (top) (top)) + #("i" "i" "i" "i"))) + (hygiene guile)) + #(syntax-object + unquote + ((top) + #(ribcage #(p) #((top)) #("i")) + #(ribcage () () ()) + #(ribcage + #(p lev) + #((top) (top)) + #("i" "i")) + #(ribcage + #(quasicons + quasiappend + quasivector + quasi) + #((top) (top) (top) (top)) + #("i" "i" "i" "i"))) + (hygiene guile))) + (#{quasi\ 2635}# + (list #{p\ 2676}#) + (- #{lev\ 2673}# 1))))) + #{tmp\ 2675}#) + ((lambda (#{tmp\ 2677}#) + (if (if #{tmp\ 2677}# + (apply (lambda (#{args\ 2678}#) + (= #{lev\ 2673}# 0)) + #{tmp\ 2677}#) + #f) + (apply (lambda (#{args\ 2679}#) + (syntax-violation + 'unquote + "unquote takes exactly one argument" + #{p\ 2672}# + (cons '#(syntax-object + unquote + ((top) + #(ribcage + #(args) + #((top)) + #("i")) + #(ribcage () () ()) + #(ribcage + #(p lev) + #((top) (top)) + #("i" "i")) + #(ribcage + #(quasicons + quasiappend + quasivector + quasi) + #((top) (top) (top) (top)) + #("i" "i" "i" "i"))) + (hygiene guile)) + #{args\ 2679}#))) + #{tmp\ 2677}#) + ((lambda (#{tmp\ 2680}#) + (if #{tmp\ 2680}# + (apply (lambda (#{p\ 2681}# #{q\ 2682}#) + (if (= #{lev\ 2673}# 0) + (#{quasiappend\ 2633}# + #{p\ 2681}# + (#{quasi\ 2635}# + #{q\ 2682}# + #{lev\ 2673}#)) + (#{quasicons\ 2632}# + (#{quasicons\ 2632}# + '(#(syntax-object + quote + ((top) + #(ribcage + #(p q) + #((top) (top)) + #("i" "i")) + #(ribcage () () ()) + #(ribcage + #(p lev) + #((top) (top)) + #("i" "i")) + #(ribcage + #(quasicons + quasiappend + quasivector + quasi) + #((top) + (top) + (top) + (top)) + #("i" "i" "i" "i"))) + (hygiene guile)) + #(syntax-object + unquote-splicing + ((top) + #(ribcage + #(p q) + #((top) (top)) + #("i" "i")) + #(ribcage () () ()) + #(ribcage + #(p lev) + #((top) (top)) + #("i" "i")) + #(ribcage + #(quasicons + quasiappend + quasivector + quasi) + #((top) + (top) + (top) + (top)) + #("i" "i" "i" "i"))) + (hygiene guile))) + (#{quasi\ 2635}# + (list #{p\ 2681}#) + (- #{lev\ 2673}# 1))) + (#{quasi\ 2635}# + #{q\ 2682}# + #{lev\ 2673}#)))) + #{tmp\ 2680}#) + ((lambda (#{tmp\ 2683}#) + (if (if #{tmp\ 2683}# + (apply (lambda (#{args\ 2684}# + #{q\ 2685}#) + (= #{lev\ 2673}# 0)) + #{tmp\ 2683}#) + #f) + (apply (lambda (#{args\ 2686}# + #{q\ 2687}#) + (syntax-violation + 'unquote-splicing + "unquote-splicing takes exactly one argument" + #{p\ 2672}# + (cons '#(syntax-object + unquote-splicing + ((top) + #(ribcage + #(args q) + #((top) (top)) + #("i" "i")) + #(ribcage + () + () + ()) + #(ribcage + #(p lev) + #((top) (top)) + #("i" "i")) + #(ribcage + #(quasicons + quasiappend + quasivector + quasi) + #((top) + (top) + (top) + (top)) + #("i" + "i" + "i" + "i"))) + (hygiene guile)) + #{args\ 2686}#))) + #{tmp\ 2683}#) + ((lambda (#{tmp\ 2688}#) + (if #{tmp\ 2688}# + (apply (lambda (#{p\ 2689}#) + (#{quasicons\ 2632}# + '(#(syntax-object + quote + ((top) + #(ribcage + #(p) + #((top)) + #("i")) + #(ribcage + () + () + ()) + #(ribcage + #(p lev) + #((top) (top)) + #("i" "i")) + #(ribcage + #(quasicons + quasiappend + quasivector + quasi) + #((top) + (top) + (top) + (top)) + #("i" + "i" + "i" + "i"))) + (hygiene guile)) + #(syntax-object + quasiquote + ((top) + #(ribcage + #(p) + #((top)) + #("i")) + #(ribcage + () + () + ()) + #(ribcage + #(p lev) + #((top) (top)) + #("i" "i")) + #(ribcage + #(quasicons + quasiappend + quasivector + quasi) + #((top) + (top) + (top) + (top)) + #("i" + "i" + "i" + "i"))) + (hygiene guile))) + (#{quasi\ 2635}# + (list #{p\ 2689}#) + (+ #{lev\ 2673}# + 1)))) + #{tmp\ 2688}#) + ((lambda (#{tmp\ 2690}#) + (if #{tmp\ 2690}# + (apply (lambda (#{p\ 2691}# + #{q\ 2692}#) + (#{quasicons\ 2632}# + (#{quasi\ 2635}# + #{p\ 2691}# + #{lev\ 2673}#) + (#{quasi\ 2635}# + #{q\ 2692}# + #{lev\ 2673}#))) + #{tmp\ 2690}#) + ((lambda (#{tmp\ 2693}#) + (if #{tmp\ 2693}# + (apply (lambda (#{x\ 2694}#) + (#{quasivector\ 2634}# + (#{quasi\ 2635}# + #{x\ 2694}# + #{lev\ 2673}#))) + #{tmp\ 2693}#) + ((lambda (#{p\ 2696}#) + (list '#(syntax-object + quote + ((top) + #(ribcage + #(p) + #((top)) + #("i")) + #(ribcage + () + () + ()) + #(ribcage + #(p lev) + #((top) + (top)) + #("i" + "i")) + #(ribcage + #(quasicons + quasiappend + quasivector + quasi) + #((top) + (top) + (top) + (top)) + #("i" + "i" + "i" + "i"))) + (hygiene + guile)) + #{p\ 2696}#)) + #{tmp\ 2674}#))) + ($sc-dispatch + #{tmp\ 2674}# + '#(vector each-any))))) + ($sc-dispatch + #{tmp\ 2674}# + '(any . any))))) + ($sc-dispatch + #{tmp\ 2674}# + '(#(free-id + #(syntax-object + quasiquote + ((top) + #(ribcage () () ()) + #(ribcage + #(p lev) + #((top) (top)) + #("i" "i")) + #(ribcage + #(quasicons + quasiappend + quasivector + quasi) + #((top) (top) (top) (top)) + #("i" "i" "i" "i"))) + (hygiene guile))) + any))))) + ($sc-dispatch + #{tmp\ 2674}# + '((#(free-id + #(syntax-object + unquote-splicing + ((top) + #(ribcage () () ()) + #(ribcage + #(p lev) + #((top) (top)) + #("i" "i")) + #(ribcage + #(quasicons + quasiappend + quasivector + quasi) + #((top) (top) (top) (top)) + #("i" "i" "i" "i"))) + (hygiene guile))) + . + any) + . + any))))) + ($sc-dispatch + #{tmp\ 2674}# + '((#(free-id + #(syntax-object + unquote-splicing + ((top) + #(ribcage () () ()) + #(ribcage + #(p lev) + #((top) (top)) + #("i" "i")) + #(ribcage + #(quasicons + quasiappend + quasivector + quasi) + #((top) (top) (top) (top)) + #("i" "i" "i" "i"))) + (hygiene guile))) + any) + . + any))))) + ($sc-dispatch + #{tmp\ 2674}# + '(#(free-id + #(syntax-object + unquote + ((top) + #(ribcage () () ()) + #(ribcage + #(p lev) + #((top) (top)) + #("i" "i")) + #(ribcage + #(quasicons quasiappend quasivector quasi) + #((top) (top) (top) (top)) + #("i" "i" "i" "i"))) + (hygiene guile))) + . + any))))) + ($sc-dispatch + #{tmp\ 2674}# + '(#(free-id + #(syntax-object + unquote + ((top) + #(ribcage () () ()) + #(ribcage #(p lev) #((top) (top)) #("i" "i")) + #(ribcage + #(quasicons quasiappend quasivector quasi) + #((top) (top) (top) (top)) + #("i" "i" "i" "i"))) + (hygiene guile))) + any)))) + #{p\ 2672}#)))) + (lambda (#{x\ 2697}#) + ((lambda (#{tmp\ 2698}#) + ((lambda (#{tmp\ 2699}#) + (if #{tmp\ 2699}# + (apply (lambda (#{_\ 2700}# #{e\ 2701}#) + (#{quasi\ 2635}# #{e\ 2701}# 0)) + #{tmp\ 2699}#) + (syntax-violation + #f + "source expression failed to match any pattern" + #{tmp\ 2698}#))) + ($sc-dispatch #{tmp\ 2698}# (quote (any any))))) + #{x\ 2697}#))))) + +(define include + (make-syncase-macro + 'macro + (lambda (#{x\ 2702}#) + (letrec ((#{read-file\ 2703}# + (lambda (#{fn\ 2704}# #{k\ 2705}#) + (let ((#{p\ 2706}# (open-input-file #{fn\ 2704}#))) + (letrec ((#{f\ 2707}# + (lambda (#{x\ 2708}#) + (if (eof-object? #{x\ 2708}#) + (begin + (close-input-port #{p\ 2706}#) + '()) + (cons (datum->syntax + #{k\ 2705}# + #{x\ 2708}#) + (#{f\ 2707}# (read #{p\ 2706}#))))))) + (#{f\ 2707}# (read #{p\ 2706}#))))))) + ((lambda (#{tmp\ 2709}#) + ((lambda (#{tmp\ 2710}#) + (if #{tmp\ 2710}# + (apply (lambda (#{k\ 2711}# #{filename\ 2712}#) + (let ((#{fn\ 2713}# + (syntax->datum #{filename\ 2712}#))) + ((lambda (#{tmp\ 2714}#) + ((lambda (#{tmp\ 2715}#) + (if #{tmp\ 2715}# + (apply (lambda (#{exp\ 2716}#) + (cons '#(syntax-object + begin + ((top) + #(ribcage + #(exp) + #((top)) + #("i")) + #(ribcage () () ()) + #(ribcage () () ()) + #(ribcage + #(fn) + #((top)) + #("i")) + #(ribcage + #(k filename) + #((top) (top)) + #("i" "i")) + #(ribcage + (read-file) + ((top)) + ("i")) + #(ribcage + #(x) + #((top)) + #("i"))) + (hygiene guile)) + #{exp\ 2716}#)) + #{tmp\ 2715}#) + (syntax-violation + #f + "source expression failed to match any pattern" + #{tmp\ 2714}#))) + ($sc-dispatch #{tmp\ 2714}# (quote each-any)))) + (#{read-file\ 2703}# #{fn\ 2713}# #{k\ 2711}#)))) + #{tmp\ 2710}#) + (syntax-violation + #f + "source expression failed to match any pattern" + #{tmp\ 2709}#))) + ($sc-dispatch #{tmp\ 2709}# (quote (any any))))) + #{x\ 2702}#))))) + +(define unquote + (make-syncase-macro + 'macro + (lambda (#{x\ 2718}#) + ((lambda (#{tmp\ 2719}#) + ((lambda (#{tmp\ 2720}#) + (if #{tmp\ 2720}# + (apply (lambda (#{_\ 2721}# #{e\ 2722}#) + (syntax-violation + 'unquote + "expression not valid outside of quasiquote" + #{x\ 2718}#)) + #{tmp\ 2720}#) + (syntax-violation + #f + "source expression failed to match any pattern" + #{tmp\ 2719}#))) + ($sc-dispatch #{tmp\ 2719}# (quote (any any))))) + #{x\ 2718}#)))) + +(define unquote-splicing + (make-syncase-macro + 'macro + (lambda (#{x\ 2723}#) + ((lambda (#{tmp\ 2724}#) + ((lambda (#{tmp\ 2725}#) + (if #{tmp\ 2725}# + (apply (lambda (#{_\ 2726}# #{e\ 2727}#) + (syntax-violation + 'unquote-splicing + "expression not valid outside of quasiquote" + #{x\ 2723}#)) + #{tmp\ 2725}#) + (syntax-violation + #f + "source expression failed to match any pattern" + #{tmp\ 2724}#))) + ($sc-dispatch #{tmp\ 2724}# (quote (any any))))) + #{x\ 2723}#)))) + +(define case + (make-extended-syncase-macro + (module-ref (current-module) (quote case)) + 'macro + (lambda (#{x\ 2728}#) + ((lambda (#{tmp\ 2729}#) + ((lambda (#{tmp\ 2730}#) + (if #{tmp\ 2730}# + (apply (lambda (#{_\ 2731}# + #{e\ 2732}# + #{m1\ 2733}# + #{m2\ 2734}#) + ((lambda (#{tmp\ 2735}#) + ((lambda (#{body\ 2736}#) + (list '#(syntax-object + let + ((top) + #(ribcage #(body) #((top)) #("i")) + #(ribcage + #(_ e m1 m2) + #((top) (top) (top) (top)) + #("i" "i" "i" "i")) + #(ribcage () () ()) + #(ribcage #(x) #((top)) #("i"))) + (hygiene guile)) + (list (list '#(syntax-object + t + ((top) + #(ribcage + #(body) + #((top)) + #("i")) + #(ribcage + #(_ e m1 m2) + #((top) (top) (top) (top)) + #("i" "i" "i" "i")) + #(ribcage () () ()) + #(ribcage + #(x) + #((top)) + #("i"))) + (hygiene guile)) + #{e\ 2732}#)) + #{body\ 2736}#)) + #{tmp\ 2735}#)) + (letrec ((#{f\ 2737}# + (lambda (#{clause\ 2738}# #{clauses\ 2739}#) + (if (null? #{clauses\ 2739}#) + ((lambda (#{tmp\ 2741}#) + ((lambda (#{tmp\ 2742}#) + (if #{tmp\ 2742}# + (apply (lambda (#{e1\ 2743}# + #{e2\ 2744}#) + (cons '#(syntax-object + begin + ((top) + #(ribcage + #(e1 e2) + #((top) + (top)) + #("i" "i")) + #(ribcage + () + () + ()) + #(ribcage + #(f + clause + clauses) + #((top) + (top) + (top)) + #("i" + "i" + "i")) + #(ribcage + #(_ + e + m1 + m2) + #((top) + (top) + (top) + (top)) + #("i" + "i" + "i" + "i")) + #(ribcage + () + () + ()) + #(ribcage + #(x) + #((top)) + #("i"))) + (hygiene + guile)) + (cons #{e1\ 2743}# + #{e2\ 2744}#))) + #{tmp\ 2742}#) + ((lambda (#{tmp\ 2746}#) + (if #{tmp\ 2746}# + (apply (lambda (#{k\ 2747}# + #{e1\ 2748}# + #{e2\ 2749}#) + (list '#(syntax-object + if + ((top) + #(ribcage + #(k + e1 + e2) + #((top) + (top) + (top)) + #("i" + "i" + "i")) + #(ribcage + () + () + ()) + #(ribcage + #(f + clause + clauses) + #((top) + (top) + (top)) + #("i" + "i" + "i")) + #(ribcage + #(_ + e + m1 + m2) + #((top) + (top) + (top) + (top)) + #("i" + "i" + "i" + "i")) + #(ribcage + () + () + ()) + #(ribcage + #(x) + #((top)) + #("i"))) + (hygiene + guile)) + (list '#(syntax-object + memv + ((top) + #(ribcage + #(k + e1 + e2) + #((top) + (top) + (top)) + #("i" + "i" + "i")) + #(ribcage + () + () + ()) + #(ribcage + #(f + clause + clauses) + #((top) + (top) + (top)) + #("i" + "i" + "i")) + #(ribcage + #(_ + e + m1 + m2) + #((top) + (top) + (top) + (top)) + #("i" + "i" + "i" + "i")) + #(ribcage + () + () + ()) + #(ribcage + #(x) + #((top)) + #("i"))) + (hygiene + guile)) + '#(syntax-object + t + ((top) + #(ribcage + #(k + e1 + e2) + #((top) + (top) + (top)) + #("i" + "i" + "i")) + #(ribcage + () + () + ()) + #(ribcage + #(f + clause + clauses) + #((top) + (top) + (top)) + #("i" + "i" + "i")) + #(ribcage + #(_ + e + m1 + m2) + #((top) + (top) + (top) + (top)) + #("i" + "i" + "i" + "i")) + #(ribcage + () + () + ()) + #(ribcage + #(x) + #((top)) + #("i"))) + (hygiene + guile)) + (list '#(syntax-object + quote + ((top) + #(ribcage + #(k + e1 + e2) + #((top) + (top) + (top)) + #("i" + "i" + "i")) + #(ribcage + () + () + ()) + #(ribcage + #(f + clause + clauses) + #((top) + (top) + (top)) + #("i" + "i" + "i")) + #(ribcage + #(_ + e + m1 + m2) + #((top) + (top) + (top) + (top)) + #("i" + "i" + "i" + "i")) + #(ribcage + () + () + ()) + #(ribcage + #(x) + #((top)) + #("i"))) + (hygiene + guile)) + #{k\ 2747}#)) + (cons '#(syntax-object + begin + ((top) + #(ribcage + #(k + e1 + e2) + #((top) + (top) + (top)) + #("i" + "i" + "i")) + #(ribcage + () + () + ()) + #(ribcage + #(f + clause + clauses) + #((top) + (top) + (top)) + #("i" + "i" + "i")) + #(ribcage + #(_ + e + m1 + m2) + #((top) + (top) + (top) + (top)) + #("i" + "i" + "i" + "i")) + #(ribcage + () + () + ()) + #(ribcage + #(x) + #((top)) + #("i"))) + (hygiene + guile)) + (cons #{e1\ 2748}# + #{e2\ 2749}#)))) + #{tmp\ 2746}#) + ((lambda (#{_\ 2752}#) + (syntax-violation + 'case + "bad clause" + #{x\ 2728}# + #{clause\ 2738}#)) + #{tmp\ 2741}#))) + ($sc-dispatch + #{tmp\ 2741}# + '(each-any + any + . + each-any))))) + ($sc-dispatch + #{tmp\ 2741}# + '(#(free-id + #(syntax-object + else + ((top) + #(ribcage () () ()) + #(ribcage + #(f clause clauses) + #((top) (top) (top)) + #("i" "i" "i")) + #(ribcage + #(_ e m1 m2) + #((top) + (top) + (top) + (top)) + #("i" "i" "i" "i")) + #(ribcage () () ()) + #(ribcage + #(x) + #((top)) + #("i"))) + (hygiene guile))) + any + . + each-any)))) + #{clause\ 2738}#) + ((lambda (#{tmp\ 2753}#) + ((lambda (#{rest\ 2754}#) + ((lambda (#{tmp\ 2755}#) + ((lambda (#{tmp\ 2756}#) + (if #{tmp\ 2756}# + (apply (lambda (#{k\ 2757}# + #{e1\ 2758}# + #{e2\ 2759}#) + (list '#(syntax-object + if + ((top) + #(ribcage + #(k + e1 + e2) + #((top) + (top) + (top)) + #("i" + "i" + "i")) + #(ribcage + #(rest) + #((top)) + #("i")) + #(ribcage + () + () + ()) + #(ribcage + #(f + clause + clauses) + #((top) + (top) + (top)) + #("i" + "i" + "i")) + #(ribcage + #(_ + e + m1 + m2) + #((top) + (top) + (top) + (top)) + #("i" + "i" + "i" + "i")) + #(ribcage + () + () + ()) + #(ribcage + #(x) + #((top)) + #("i"))) + (hygiene + guile)) + (list '#(syntax-object + memv + ((top) + #(ribcage + #(k + e1 + e2) + #((top) + (top) + (top)) + #("i" + "i" + "i")) + #(ribcage + #(rest) + #((top)) + #("i")) + #(ribcage + () + () + ()) + #(ribcage + #(f + clause + clauses) + #((top) + (top) + (top)) + #("i" + "i" + "i")) + #(ribcage + #(_ + e + m1 + m2) + #((top) + (top) + (top) + (top)) + #("i" + "i" + "i" + "i")) + #(ribcage + () + () + ()) + #(ribcage + #(x) + #((top)) + #("i"))) + (hygiene + guile)) + '#(syntax-object + t + ((top) + #(ribcage + #(k + e1 + e2) + #((top) + (top) + (top)) + #("i" + "i" + "i")) + #(ribcage + #(rest) + #((top)) + #("i")) + #(ribcage + () + () + ()) + #(ribcage + #(f + clause + clauses) + #((top) + (top) + (top)) + #("i" + "i" + "i")) + #(ribcage + #(_ + e + m1 + m2) + #((top) + (top) + (top) + (top)) + #("i" + "i" + "i" + "i")) + #(ribcage + () + () + ()) + #(ribcage + #(x) + #((top)) + #("i"))) + (hygiene + guile)) + (list '#(syntax-object + quote + ((top) + #(ribcage + #(k + e1 + e2) + #((top) + (top) + (top)) + #("i" + "i" + "i")) + #(ribcage + #(rest) + #((top)) + #("i")) + #(ribcage + () + () + ()) + #(ribcage + #(f + clause + clauses) + #((top) + (top) + (top)) + #("i" + "i" + "i")) + #(ribcage + #(_ + e + m1 + m2) + #((top) + (top) + (top) + (top)) + #("i" + "i" + "i" + "i")) + #(ribcage + () + () + ()) + #(ribcage + #(x) + #((top)) + #("i"))) + (hygiene + guile)) + #{k\ 2757}#)) + (cons '#(syntax-object + begin + ((top) + #(ribcage + #(k + e1 + e2) + #((top) + (top) + (top)) + #("i" + "i" + "i")) + #(ribcage + #(rest) + #((top)) + #("i")) + #(ribcage + () + () + ()) + #(ribcage + #(f + clause + clauses) + #((top) + (top) + (top)) + #("i" + "i" + "i")) + #(ribcage + #(_ + e + m1 + m2) + #((top) + (top) + (top) + (top)) + #("i" + "i" + "i" + "i")) + #(ribcage + () + () + ()) + #(ribcage + #(x) + #((top)) + #("i"))) + (hygiene + guile)) + (cons #{e1\ 2758}# + #{e2\ 2759}#)) + #{rest\ 2754}#)) + #{tmp\ 2756}#) + ((lambda (#{_\ 2762}#) + (syntax-violation + 'case + "bad clause" + #{x\ 2728}# + #{clause\ 2738}#)) + #{tmp\ 2755}#))) + ($sc-dispatch + #{tmp\ 2755}# + '(each-any + any + . + each-any)))) + #{clause\ 2738}#)) + #{tmp\ 2753}#)) + (#{f\ 2737}# + (car #{clauses\ 2739}#) + (cdr #{clauses\ 2739}#))))))) + (#{f\ 2737}# #{m1\ 2733}# #{m2\ 2734}#)))) + #{tmp\ 2730}#) + (syntax-violation + #f + "source expression failed to match any pattern" + #{tmp\ 2729}#))) + ($sc-dispatch + #{tmp\ 2729}# + '(any any any . each-any)))) + #{x\ 2728}#)))) + +(define identifier-syntax + (make-syncase-macro + 'macro + (lambda (#{x\ 2763}#) + ((lambda (#{tmp\ 2764}#) + ((lambda (#{tmp\ 2765}#) + (if #{tmp\ 2765}# + (apply (lambda (#{_\ 2766}# #{e\ 2767}#) + (list '#(syntax-object + lambda + ((top) + #(ribcage #(_ e) #((top) (top)) #("i" "i")) + #(ribcage () () ()) + #(ribcage #(x) #((top)) #("i"))) + (hygiene guile)) + '(#(syntax-object + x + ((top) + #(ribcage #(_ e) #((top) (top)) #("i" "i")) + #(ribcage () () ()) + #(ribcage #(x) #((top)) #("i"))) + (hygiene guile))) + (list '#(syntax-object + syntax-case + ((top) + #(ribcage + #(_ e) + #((top) (top)) + #("i" "i")) + #(ribcage () () ()) + #(ribcage #(x) #((top)) #("i"))) + (hygiene guile)) + '#(syntax-object + x + ((top) + #(ribcage + #(_ e) + #((top) (top)) + #("i" "i")) + #(ribcage () () ()) + #(ribcage #(x) #((top)) #("i"))) + (hygiene guile)) + '() + (list '#(syntax-object + id + ((top) + #(ribcage + #(_ e) + #((top) (top)) + #("i" "i")) + #(ribcage () () ()) + #(ribcage #(x) #((top)) #("i"))) + (hygiene guile)) + '(#(syntax-object + identifier? + ((top) + #(ribcage + #(_ e) + #((top) (top)) + #("i" "i")) + #(ribcage () () ()) + #(ribcage #(x) #((top)) #("i"))) + (hygiene guile)) + (#(syntax-object + syntax + ((top) + #(ribcage + #(_ e) + #((top) (top)) + #("i" "i")) + #(ribcage () () ()) + #(ribcage #(x) #((top)) #("i"))) + (hygiene guile)) + #(syntax-object + id + ((top) + #(ribcage + #(_ e) + #((top) (top)) + #("i" "i")) + #(ribcage () () ()) + #(ribcage #(x) #((top)) #("i"))) + (hygiene guile)))) + (list '#(syntax-object + syntax + ((top) + #(ribcage + #(_ e) + #((top) (top)) + #("i" "i")) + #(ribcage () () ()) + #(ribcage + #(x) + #((top)) + #("i"))) + (hygiene guile)) + #{e\ 2767}#)) + (list (cons #{_\ 2766}# + '(#(syntax-object + x + ((top) + #(ribcage + #(_ e) + #((top) (top)) + #("i" "i")) + #(ribcage () () ()) + #(ribcage + #(x) + #((top)) + #("i"))) + (hygiene guile)) + #(syntax-object + ... + ((top) + #(ribcage + #(_ e) + #((top) (top)) + #("i" "i")) + #(ribcage () () ()) + #(ribcage + #(x) + #((top)) + #("i"))) + (hygiene guile)))) + (list '#(syntax-object + syntax + ((top) + #(ribcage + #(_ e) + #((top) (top)) + #("i" "i")) + #(ribcage () () ()) + #(ribcage + #(x) + #((top)) + #("i"))) + (hygiene guile)) + (cons #{e\ 2767}# + '(#(syntax-object + x + ((top) + #(ribcage + #(_ e) + #((top) (top)) + #("i" "i")) + #(ribcage () () ()) + #(ribcage + #(x) + #((top)) + #("i"))) + (hygiene guile)) + #(syntax-object + ... + ((top) + #(ribcage + #(_ e) + #((top) (top)) + #("i" "i")) + #(ribcage () () ()) + #(ribcage + #(x) + #((top)) + #("i"))) + (hygiene + guile))))))))) + #{tmp\ 2765}#) + (syntax-violation + #f + "source expression failed to match any pattern" + #{tmp\ 2764}#))) + ($sc-dispatch #{tmp\ 2764}# (quote (any any))))) + #{x\ 2763}#)))) + diff --git a/module/ice-9/psyntax.scm b/module/ice-9/psyntax.scm index 687e0e5bf..cb90fcc17 100644 --- a/module/ice-9/psyntax.scm +++ b/module/ice-9/psyntax.scm @@ -1,11 +1,11 @@ ;;;; -*-scheme-*- ;;;; -;;;; Copyright (C) 2001, 2003, 2006 Free Software Foundation, Inc. +;;;; Copyright (C) 2001, 2003, 2006, 2009 Free Software Foundation, Inc. ;;;; ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -22,6 +22,9 @@ ;;; Extracted from Chez Scheme Version 5.9f ;;; Authors: R. Kent Dybvig, Oscar Waddell, Bob Hieb, Carl Bruggeman +;;; Modified by Andy Wingo according to the Git +;;; revision control logs corresponding to this file: 2009. + ;;; Modified by Mikael Djurfeldt according ;;; to the ChangeLog distributed in the same directory as this file: ;;; 1997-08-19, 1997-09-03, 1997-09-10, 2000-08-13, 2000-08-24, @@ -49,7 +52,7 @@ ;;; also documented in the R4RS and draft R5RS. ;;; ;;; bound-identifier=? -;;; datum->syntax-object +;;; datum->syntax ;;; define-syntax ;;; fluid-let-syntax ;;; free-identifier=? @@ -60,7 +63,7 @@ ;;; letrec-syntax ;;; syntax ;;; syntax-case -;;; syntax-object->datum +;;; syntax->datum ;;; syntax-rules ;;; with-syntax ;;; @@ -79,46 +82,14 @@ ;;; conditionally evaluates expr ... at compile-time or run-time ;;; depending upon situations (see the Chez Scheme System Manual, ;;; Revision 3, for a complete description) -;;; (syntax-error object message) +;;; (syntax-violation who message form [subform]) ;;; used to report errors found during expansion -;;; (install-global-transformer symbol value) -;;; used by expanded code to install top-level syntactic abstractions -;;; (syntax-dispatch e p) +;;; ($sc-dispatch e p) ;;; used by expanded code to handle syntax-case matching ;;; The following nonstandard procedures must be provided by the -;;; implementation for this code to run. -;;; -;;; (void) -;;; returns the implementation's cannonical "unspecified value". This -;;; usually works: (define void (lambda () (if #f #f))). -;;; -;;; (andmap proc list1 list2 ...) -;;; returns true if proc returns true when applied to each element of list1 -;;; along with the corresponding elements of list2 .... -;;; The following definition works but does no error checking: -;;; -;;; (define andmap -;;; (lambda (f first . rest) -;;; (or (null? first) -;;; (if (null? rest) -;;; (let andmap ((first first)) -;;; (let ((x (car first)) (first (cdr first))) -;;; (if (null? first) -;;; (f x) -;;; (and (f x) (andmap first))))) -;;; (let andmap ((first first) (rest rest)) -;;; (let ((x (car first)) -;;; (xr (map car rest)) -;;; (first (cdr first)) -;;; (rest (map cdr rest))) -;;; (if (null? first) -;;; (apply f (cons x xr)) -;;; (and (apply f (cons x xr)) (andmap first rest))))))))) -;;; -;;; The following nonstandard procedures must also be provided by the ;;; implementation for this code to run using the standard portable -;;; hooks and output constructors. They are not used by expanded code, +;;; hooks and output constructors. They are not used by expanded code, ;;; and so need be present only at expansion time. ;;; ;;; (eval x) @@ -134,21 +105,8 @@ ;;; by eval, and eval accepts one argument, nothing special must be done ;;; to support the "noexpand" flag, since it is handled by sc-expand. ;;; -;;; (error who format-string why what) -;;; where who is either a symbol or #f, format-string is always "~a ~s", -;;; why is always a string, and what may be any object. error should -;;; signal an error with a message something like -;;; -;;; "error in : " -;;; ;;; (gensym) ;;; returns a unique symbol each time it's called -;;; -;;; (putprop symbol key value) -;;; (getprop symbol key) -;;; key is always the symbol *sc-expander*; value may be any object. -;;; putprop should associate the given value with the given symbol in -;;; some way that it can be retrieved later with getprop. ;;; When porting to a new Scheme implementation, you should define the ;;; procedures listed above, load the expanded version of psyntax.ss @@ -209,7 +167,7 @@ ;;; Objects with no standard print syntax, including objects containing ;;; cycles and syntax object, are allowed in quoted data as long as they -;;; are contained within a syntax form or produced by datum->syntax-object. +;;; are contained within a syntax form or produced by datum->syntax. ;;; Such objects are never copied. ;;; All identifiers that don't have macro definitions and are not bound @@ -233,19 +191,6 @@ ;;; The implementation of generate-temporaries assumes that it is possible ;;; to generate globally unique symbols (gensyms). -;;; The input to sc-expand may contain "annotations" describing, e.g., the -;;; source file and character position from where each object was read if -;;; it was read from a file. These annotations are handled properly by -;;; sc-expand only if the annotation? hook (see hooks below) is implemented -;;; properly and the operators make-annotation, annotation-expression, -;;; annotation-source, annotation-stripped, and set-annotation-stripped! -;;; are supplied. If annotations are supplied, the proper annotation -;;; source is passed to the various output constructors, allowing -;;; implementations to accurately correlate source and expanded code. -;;; Contact one of the authors for details if you wish to make use of -;;; this feature. - - ;;; Bootstrapping: @@ -256,23 +201,45 @@ +(eval-when (compile) + (set-current-module (resolve-module '(guile)))) + (let () +;;; Private version of and-map that handles multiple lists. +(define and-map* + (lambda (f first . rest) + (or (null? first) + (if (null? rest) + (let andmap ((first first)) + (let ((x (car first)) (first (cdr first))) + (if (null? first) + (f x) + (and (f x) (andmap first))))) + (let andmap ((first first) (rest rest)) + (let ((x (car first)) + (xr (map car rest)) + (first (cdr first)) + (rest (map cdr rest))) + (if (null? first) + (apply f (cons x xr)) + (and (apply f (cons x xr)) (andmap first rest))))))))) + (define-syntax define-structure (lambda (x) (define construct-name (lambda (template-identifier . args) - (datum->syntax-object + (datum->syntax template-identifier (string->symbol (apply string-append (map (lambda (x) (if (string? x) x - (symbol->string (syntax-object->datum x)))) + (symbol->string (syntax->datum x)))) args)))))) (syntax-case x () ((_ (name id1 ...)) - (andmap identifier? (syntax (name id1 ...))) + (and-map identifier? (syntax (name id1 ...))) (with-syntax ((constructor (construct-name (syntax name) "make-" (syntax name))) (predicate (construct-name (syntax name) (syntax name) "?")) @@ -310,6 +277,7 @@ (let () (define noexpand "noexpand") +(define *mode* (make-fluid)) ;;; hooks to nonportable run-time helpers (begin @@ -319,143 +287,273 @@ (define fx< <) (define top-level-eval-hook - (lambda (x) - (eval `(,noexpand ,x) (interaction-environment)))) + (lambda (x mod) + (primitive-eval + `(,noexpand + ,(case (fluid-ref *mode*) + ((c) ((@ (language tree-il) tree-il->scheme) x)) + (else x)))))) (define local-eval-hook - (lambda (x) - (eval `(,noexpand ,x) (interaction-environment)))) - -(define error-hook - (lambda (who why what) - (error who "~a ~s" why what))) + (lambda (x mod) + (primitive-eval + `(,noexpand + ,(case (fluid-ref *mode*) + ((c) ((@ (language tree-il) tree-il->scheme) x)) + (else x)))))) (define-syntax gensym-hook (syntax-rules () ((_) (gensym)))) (define put-global-definition-hook - (lambda (symbol binding) - (putprop symbol '*sc-expander* binding))) + (lambda (symbol type val) + (let ((existing (let ((v (module-variable (current-module) symbol))) + (and v (variable-bound? v) + (let ((val (variable-ref v))) + (and (macro? val) + (not (syncase-macro-type val)) + val)))))) + (module-define! (current-module) + symbol + (if existing + (make-extended-syncase-macro existing type val) + (make-syncase-macro type val)))))) (define get-global-definition-hook - (lambda (symbol) - (getprop symbol '*sc-expander*))) + (lambda (symbol module) + (if (and (not module) (current-module)) + (warn "module system is booted, we should have a module" symbol)) + (let ((v (module-variable (if module + (resolve-module (cdr module)) + (current-module)) + symbol))) + (and v (variable-bound? v) + (let ((val (variable-ref v))) + (and (macro? val) (syncase-macro-type val) + (cons (syncase-macro-type val) + (syncase-macro-binding val)))))))) + ) +(define (decorate-source e s) + (if (and (pair? e) s) + (set-source-properties! e s)) + e) + ;;; output constructors -(define (build-annotated src exp) - (if (and src (not (annotation? exp))) - (make-annotation exp src #t) - exp)) +(define build-void + (lambda (source) + (case (fluid-ref *mode*) + ((c) ((@ (language tree-il) make-void) source)) + (else (decorate-source '(if #f #f) source))))) -(define-syntax build-application - (syntax-rules () - ((_ source fun-exp arg-exps) - (build-annotated source `(,fun-exp . ,arg-exps))))) +(define build-application + (lambda (source fun-exp arg-exps) + (case (fluid-ref *mode*) + ((c) ((@ (language tree-il) make-application) source fun-exp arg-exps)) + (else (decorate-source `(,fun-exp . ,arg-exps) source))))) -(define-syntax build-conditional - (syntax-rules () - ((_ source test-exp then-exp else-exp) - (build-annotated source `(if ,test-exp ,then-exp ,else-exp))))) +(define build-conditional + (lambda (source test-exp then-exp else-exp) + (case (fluid-ref *mode*) + ((c) ((@ (language tree-il) make-conditional) + source test-exp then-exp else-exp)) + (else (decorate-source + (if (equal? else-exp '(if #f #f)) + `(if ,test-exp ,then-exp) + `(if ,test-exp ,then-exp ,else-exp)) + source))))) -(define-syntax build-lexical-reference - (syntax-rules () - ((_ type source var) - (build-annotated source var)))) +(define build-lexical-reference + (lambda (type source name var) + (case (fluid-ref *mode*) + ((c) ((@ (language tree-il) make-lexical-ref) source name var)) + (else (decorate-source var source))))) -(define-syntax build-lexical-assignment - (syntax-rules () - ((_ source var exp) - (build-annotated source `(set! ,var ,exp))))) +(define build-lexical-assignment + (lambda (source name var exp) + (case (fluid-ref *mode*) + ((c) ((@ (language tree-il) make-lexical-set) source name var exp)) + (else (decorate-source `(set! ,var ,exp) source))))) -(define-syntax build-global-reference - (syntax-rules () - ((_ source var) - (build-annotated source var)))) +;; Before modules are booted, we can't expand into data structures from +;; (language tree-il) -- we need to give the evaluator the +;; s-expressions that it understands natively. Actually the real truth +;; of the matter is that the evaluator doesn't understand tree-il +;; structures at all. So until we fix the evaluator, if ever, the +;; conflation that we should use tree-il iff we are compiling +;; holds true. +;; +(define (analyze-variable mod var modref-cont bare-cont) + (if (not mod) + (bare-cont var) + (let ((kind (car mod)) + (mod (cdr mod))) + (case kind + ((public) (modref-cont mod var #t)) + ((private) (if (not (equal? mod (module-name (current-module)))) + (modref-cont mod var #f) + (bare-cont var))) + ((bare) (bare-cont var)) + ((hygiene) (if (and (not (equal? mod (module-name (current-module)))) + (module-variable (resolve-module mod) var)) + (modref-cont mod var #f) + (bare-cont var))) + (else (syntax-violation #f "bad module kind" var mod)))))) -(define-syntax build-global-assignment - (syntax-rules () - ((_ source var exp) - (build-annotated source `(set! ,var ,exp))))) +(define build-global-reference + (lambda (source var mod) + (analyze-variable + mod var + (lambda (mod var public?) + (case (fluid-ref *mode*) + ((c) ((@ (language tree-il) make-module-ref) source mod var public?)) + (else (decorate-source (list (if public? '@ '@@) mod var) source)))) + (lambda (var) + (case (fluid-ref *mode*) + ((c) ((@ (language tree-il) make-toplevel-ref) source var)) + (else (decorate-source var source))))))) -(define-syntax build-global-definition - (syntax-rules () - ((_ source var exp) - (build-annotated source `(define ,var ,exp))))) +(define build-global-assignment + (lambda (source var exp mod) + (analyze-variable + mod var + (lambda (mod var public?) + (case (fluid-ref *mode*) + ((c) ((@ (language tree-il) make-module-set) source mod var public? exp)) + (else (decorate-source `(set! ,(list (if public? '@ '@@) mod var) ,exp) source)))) + (lambda (var) + (case (fluid-ref *mode*) + ((c) ((@ (language tree-il) make-toplevel-set) source var exp)) + (else (decorate-source `(set! ,var ,exp) source))))))) -(define-syntax build-lambda - (syntax-rules () - ((_ src vars exp) - (build-annotated src `(lambda ,vars ,exp))))) +;; FIXME: there is a bug that prevents (set! ((@ (foo) bar) baz) quz) +;; from working. Hack around it. +(define (maybe-name-value! name val) + (cond + (((@ (language tree-il) lambda?) val) + (let ((meta ((@ (language tree-il) lambda-meta) val))) + (if (not (assq 'name meta)) + ((setter (@ (language tree-il) lambda-meta)) + val + (acons 'name name meta))))))) -(define-syntax build-primref - (syntax-rules () - ((_ src name) (build-annotated src name)) - ((_ src level name) (build-annotated src name)))) +(define build-global-definition + (lambda (source var exp) + (case (fluid-ref *mode*) + ((c) + (maybe-name-value! var exp) + ((@ (language tree-il) make-toplevel-define) source var exp)) + (else (decorate-source `(define ,var ,exp) source))))) + +(define build-lambda + (lambda (src ids vars docstring exp) + (case (fluid-ref *mode*) + ((c) ((@ (language tree-il) make-lambda) src ids vars + (if docstring `((documentation . ,docstring)) '()) + exp)) + (else (decorate-source + `(lambda ,vars ,@(if docstring (list docstring) '()) + ,exp) + src))))) + +(define build-primref + (lambda (src name) + (if (equal? (module-name (current-module)) '(guile)) + (case (fluid-ref *mode*) + ((c) ((@ (language tree-il) make-toplevel-ref) src name)) + (else (decorate-source name src))) + (case (fluid-ref *mode*) + ((c) ((@ (language tree-il) make-module-ref) src '(guile) name #f)) + (else (decorate-source `(@@ (guile) ,name) src)))))) (define (build-data src exp) - (if (and (self-evaluating? exp) - (not (vector? exp))) - (build-annotated src exp) - (build-annotated src (list 'quote exp)))) + (case (fluid-ref *mode*) + ((c) ((@ (language tree-il) make-const) src exp)) + (else (decorate-source + (if (and (self-evaluating? exp) (not (vector? exp))) + exp + (list 'quote exp)) + src)))) (define build-sequence (lambda (src exps) (if (null? (cdr exps)) - (build-annotated src (car exps)) - (build-annotated src `(begin ,@exps))))) + (car exps) + (case (fluid-ref *mode*) + ((c) ((@ (language tree-il) make-sequence) src exps)) + (else (decorate-source `(begin ,@exps) src)))))) (define build-let - (lambda (src vars val-exps body-exp) + (lambda (src ids vars val-exps body-exp) (if (null? vars) - (build-annotated src body-exp) - (build-annotated src `(let ,(map list vars val-exps) ,body-exp))))) + body-exp + (case (fluid-ref *mode*) + ((c) + (for-each maybe-name-value! ids val-exps) + ((@ (language tree-il) make-let) src ids vars val-exps body-exp)) + (else (decorate-source + `(let ,(map list vars val-exps) ,body-exp) + src)))))) (define build-named-let - (lambda (src vars val-exps body-exp) - (if (null? vars) - (build-annotated src body-exp) - (build-annotated src - `(let ,(car vars) - ,(map list (cdr vars) val-exps) ,body-exp))))) + (lambda (src ids vars val-exps body-exp) + (let ((f (car vars)) + (f-name (car ids)) + (vars (cdr vars)) + (ids (cdr ids))) + (case (fluid-ref *mode*) + ((c) + (let ((proc (build-lambda src ids vars #f body-exp))) + (maybe-name-value! f-name proc) + (for-each maybe-name-value! ids val-exps) + ((@ (language tree-il) make-letrec) src + (list f-name) (list f) (list proc) + (build-application src (build-lexical-reference 'fun src f-name f) + val-exps)))) + (else (decorate-source + `(let ,f ,(map list vars val-exps) ,body-exp) + src)))))) (define build-letrec - (lambda (src vars val-exps body-exp) + (lambda (src ids vars val-exps body-exp) (if (null? vars) - (build-annotated src body-exp) - (build-annotated src - `(letrec ,(map list vars val-exps) ,body-exp))))) + body-exp + (case (fluid-ref *mode*) + ((c) + (for-each maybe-name-value! ids val-exps) + ((@ (language tree-il) make-letrec) src ids vars val-exps body-exp)) + (else (decorate-source + `(letrec ,(map list vars val-exps) ,body-exp) + src)))))) +;; FIXME: use a faster gensym (define-syntax build-lexical-var (syntax-rules () - ((_ src id) (build-annotated src (gensym (symbol->string id)))))) + ((_ src id) (gensym (string-append (symbol->string id) " "))))) -(define-structure (syntax-object expression wrap)) - -(define-syntax unannotate - (syntax-rules () - ((_ x) - (let ((e x)) - (if (annotation? e) - (annotation-expression e) - e))))) +(define-structure (syntax-object expression wrap module)) (define-syntax no-source (identifier-syntax #f)) (define source-annotation (lambda (x) (cond - ((annotation? x) (annotation-source x)) - ((syntax-object? x) (source-annotation (syntax-object-expression x))) - (else no-source)))) + ((syntax-object? x) + (source-annotation (syntax-object-expression x))) + ((pair? x) (let ((props (source-properties x))) + (if (pair? props) + props + #f))) + (else #f)))) (define-syntax arg-check (syntax-rules () ((_ pred? e who) (let ((x e)) - (if (not (pred? x)) (error-hook who "invalid argument" x)))))) + (if (not (pred? x)) (syntax-violation who "invalid argument" x)))))) ;;; compile-time environments @@ -479,7 +577,7 @@ ;;; ::= (macro . ) macros ;;; (core . ) core forms -;;; (external-macro . ) external-macro +;;; (module-ref . ) @ or @@ ;;; (begin) begin ;;; (define) define ;;; (define-syntax) define-syntax @@ -555,16 +653,16 @@ ; although symbols are usually global, we check the environment first ; anyway because a temporary binding may have been established by ; fluid-let-syntax - (lambda (x r) + (lambda (x r mod) (cond ((assq x r) => cdr) ((symbol? x) - (or (get-global-definition-hook x) (make-binding 'global))) + (or (get-global-definition-hook x mod) (make-binding 'global))) (else (make-binding 'displaced-lexical))))) (define global-extend (lambda (type sym val) - (put-global-definition-hook sym (make-binding type val)))) + (put-global-definition-hook sym type val))) ;;; Conceptually, identifiers are always syntax objects. Internally, @@ -575,29 +673,30 @@ (define nonsymbol-id? (lambda (x) (and (syntax-object? x) - (symbol? (unannotate (syntax-object-expression x)))))) + (symbol? (syntax-object-expression x))))) (define id? (lambda (x) (cond ((symbol? x) #t) - ((syntax-object? x) (symbol? (unannotate (syntax-object-expression x)))) - ((annotation? x) (symbol? (annotation-expression x))) + ((syntax-object? x) (symbol? (syntax-object-expression x))) (else #f)))) (define-syntax id-sym-name (syntax-rules () ((_ e) (let ((x e)) - (unannotate (if (syntax-object? x) (syntax-object-expression x) x)))))) + (if (syntax-object? x) + (syntax-object-expression x) + x))))) (define id-sym-name&marks (lambda (x w) (if (syntax-object? x) (values - (unannotate (syntax-object-expression x)) - (join-marks (wrap-marks w) (wrap-marks (syntax-object-wrap x)))) - (values (unannotate x) (wrap-marks w))))) + (syntax-object-expression x) + (join-marks (wrap-marks w) (wrap-marks (syntax-object-wrap x)))) + (values x (wrap-marks w))))) ;;; syntax object wraps @@ -663,7 +762,7 @@ ; must receive ids with complete wraps (lambda (ribcage id label) (set-ribcage-symnames! ribcage - (cons (unannotate (syntax-object-expression id)) + (cons (syntax-object-expression id) (ribcage-symnames ribcage))) (set-ribcage-marks! ribcage (cons (wrap-marks (syntax-object-wrap id)) @@ -763,7 +862,7 @@ ((symbol? id) (or (first (search id (wrap-subst w) (wrap-marks w))) id)) ((syntax-object? id) - (let ((id (unannotate (syntax-object-expression id))) + (let ((id (syntax-object-expression id)) (w1 (syntax-object-wrap id))) (let ((marks (join-marks (wrap-marks w) (wrap-marks w1)))) (call-with-values (lambda () (search id (wrap-subst w) marks)) @@ -771,10 +870,7 @@ (or new-id (first (search id (wrap-subst w1) marks)) id)))))) - ((annotation? id) - (let ((id (unannotate id))) - (or (first (search id (wrap-subst w) (wrap-marks w))) id))) - (else (error-hook 'id-var-name "invalid id" id))))) + (else (syntax-violation 'id-var-name "invalid id" id))))) ;;; free-id=? must be passed fully wrapped ids since (free-id=? x y) ;;; may be true even if (free-id=? (wrap x w) (wrap y w)) is not. @@ -791,11 +887,11 @@ (define bound-id=? (lambda (i j) (if (and (syntax-object? i) (syntax-object? j)) - (and (eq? (unannotate (syntax-object-expression i)) - (unannotate (syntax-object-expression j))) + (and (eq? (syntax-object-expression i) + (syntax-object-expression j)) (same-marks? (wrap-marks (syntax-object-wrap i)) (wrap-marks (syntax-object-wrap j)))) - (eq? (unannotate i) (unannotate j))))) + (eq? i j)))) ;;; "valid-bound-ids?" returns #t if it receives a list of distinct ids. ;;; valid-bound-ids? may be passed unwrapped (or partially wrapped) ids @@ -832,45 +928,68 @@ ;;; wrapping expressions and identifiers (define wrap - (lambda (x w) + (lambda (x w defmod) (cond ((and (null? (wrap-marks w)) (null? (wrap-subst w))) x) ((syntax-object? x) (make-syntax-object (syntax-object-expression x) - (join-wraps w (syntax-object-wrap x)))) + (join-wraps w (syntax-object-wrap x)) + (syntax-object-module x))) ((null? x) x) - (else (make-syntax-object x w))))) + (else (make-syntax-object x w defmod))))) (define source-wrap - (lambda (x w s) - (wrap (if s (make-annotation x s #f) x) w))) + (lambda (x w s defmod) + (wrap (decorate-source x s) w defmod))) ;;; expanding (define chi-sequence - (lambda (body r w s) + (lambda (body r w s mod) (build-sequence s - (let dobody ((body body) (r r) (w w)) + (let dobody ((body body) (r r) (w w) (mod mod)) (if (null? body) '() - (let ((first (chi (car body) r w))) - (cons first (dobody (cdr body) r w)))))))) + (let ((first (chi (car body) r w mod))) + (cons first (dobody (cdr body) r w mod)))))))) (define chi-top-sequence - (lambda (body r w s m esew) + (lambda (body r w s m esew mod) (build-sequence s - (let dobody ((body body) (r r) (w w) (m m) (esew esew)) + (let dobody ((body body) (r r) (w w) (m m) (esew esew) (mod mod)) (if (null? body) '() - (let ((first (chi-top (car body) r w m esew))) - (cons first (dobody (cdr body) r w m esew)))))))) + (let ((first (chi-top (car body) r w m esew mod))) + (cons first (dobody (cdr body) r w m esew mod)))))))) (define chi-install-global (lambda (name e) - (build-application no-source - (build-primref no-source 'install-global-transformer) - (list (build-data no-source name) e)))) + (build-global-definition + no-source + name + ;; FIXME: seems nasty to call current-module here + (if (let ((v (module-variable (current-module) name))) + ;; FIXME use primitive-macro? + (and v (variable-bound? v) (macro? (variable-ref v)) + (not (eq? (macro-type (variable-ref v)) 'syncase-macro)))) + (build-application + no-source + (build-primref no-source 'make-extended-syncase-macro) + (list (build-application + no-source + (build-primref no-source 'module-ref) + (list (build-application + no-source + (build-primref no-source 'current-module) + '()) + (build-data no-source name))) + (build-data no-source 'macro) + e)) + (build-application + no-source + (build-primref no-source 'make-syncase-macro) + (list (build-data no-source 'macro) e)))))) (define chi-when-list (lambda (e when-list w) @@ -884,17 +1003,19 @@ ((free-id=? x (syntax compile)) 'compile) ((free-id=? x (syntax load)) 'load) ((free-id=? x (syntax eval)) 'eval) - (else (syntax-error (wrap x w) - "invalid eval-when situation")))) + (else (syntax-violation 'eval-when + "invalid situation" + e (wrap x w #f))))) situations)))))) -;;; syntax-type returns five values: type, value, e, w, and s. The first -;;; two are described in the table below. +;;; syntax-type returns six values: type, value, e, w, s, and mod. The +;;; first two are described in the table below. ;;; ;;; type value explanation ;;; ------------------------------------------------------------------- -;;; core procedure core form (including singleton) -;;; external-macro procedure external macro +;;; core procedure core singleton +;;; core-form procedure core form +;;; module-ref procedure @ or @@ singleton ;;; lexical name lexical variable reference ;;; global name global variable reference ;;; begin none begin keyword @@ -917,99 +1038,113 @@ ;;; ;;; For define-form and define-syntax-form, e is the rhs expression. ;;; For all others, e is the entire form. w is the wrap for e. -;;; s is the source for the entire form. +;;; s is the source for the entire form. mod is the module for e. ;;; ;;; syntax-type expands macros and unwraps as necessary to get to ;;; one of the forms above. It also parses define and define-syntax ;;; forms, although perhaps this should be done by the consumer. (define syntax-type - (lambda (e r w s rib) + (lambda (e r w s rib mod for-car?) (cond ((symbol? e) (let* ((n (id-var-name e w)) - (b (lookup n r)) + (b (lookup n r mod)) (type (binding-type b))) (case type - ((lexical) (values type (binding-value b) e w s)) - ((global) (values type n e w s)) + ((lexical) (values type (binding-value b) e w s mod)) + ((global) (values type n e w s mod)) ((macro) - (syntax-type (chi-macro (binding-value b) e r w rib) r empty-wrap s rib)) - (else (values type (binding-value b) e w s))))) + (if for-car? + (values type (binding-value b) e w s mod) + (syntax-type (chi-macro (binding-value b) e r w rib mod) + r empty-wrap s rib mod #f))) + (else (values type (binding-value b) e w s mod))))) ((pair? e) (let ((first (car e))) - (if (id? first) - (let* ((n (id-var-name first w)) - (b (lookup n r)) - (type (binding-type b))) - (case type - ((lexical) (values 'lexical-call (binding-value b) e w s)) - ((global) (values 'global-call n e w s)) - ((macro) - (syntax-type (chi-macro (binding-value b) e r w rib) - r empty-wrap s rib)) - ((core external-macro) (values type (binding-value b) e w s)) - ((local-syntax) - (values 'local-syntax-form (binding-value b) e w s)) - ((begin) (values 'begin-form #f e w s)) - ((eval-when) (values 'eval-when-form #f e w s)) - ((define) - (syntax-case e () - ((_ name val) - (id? (syntax name)) - (values 'define-form (syntax name) (syntax val) w s)) - ((_ (name . args) e1 e2 ...) - (and (id? (syntax name)) - (valid-bound-ids? (lambda-var-list (syntax args)))) - ; need lambda here... - (values 'define-form (wrap (syntax name) w) - (cons (syntax lambda) (wrap (syntax (args e1 e2 ...)) w)) - empty-wrap s)) - ((_ name) - (id? (syntax name)) - (values 'define-form (wrap (syntax name) w) - (syntax (void)) - empty-wrap s)))) - ((define-syntax) - (syntax-case e () - ((_ name val) - (id? (syntax name)) - (values 'define-syntax-form (syntax name) - (syntax val) w s)))) - (else (values 'call #f e w s)))) - (values 'call #f e w s)))) + (call-with-values + (lambda () (syntax-type first r w s rib mod #t)) + (lambda (ftype fval fe fw fs fmod) + (case ftype + ((lexical) + (values 'lexical-call fval e w s mod)) + ((global) + ;; If we got here via an (@@ ...) expansion, we need to + ;; make sure the fmod information is propagated back + ;; correctly -- hence this consing. + (values 'global-call (make-syntax-object fval w fmod) + e w s mod)) + ((macro) + (syntax-type (chi-macro fval e r w rib mod) + r empty-wrap s rib mod for-car?)) + ((module-ref) + (call-with-values (lambda () (fval e)) + (lambda (sym mod) + (syntax-type sym r w s rib mod for-car?)))) + ((core) + (values 'core-form fval e w s mod)) + ((local-syntax) + (values 'local-syntax-form fval e w s mod)) + ((begin) + (values 'begin-form #f e w s mod)) + ((eval-when) + (values 'eval-when-form #f e w s mod)) + ((define) + (syntax-case e () + ((_ name val) + (id? (syntax name)) + (values 'define-form (syntax name) (syntax val) w s mod)) + ((_ (name . args) e1 e2 ...) + (and (id? (syntax name)) + (valid-bound-ids? (lambda-var-list (syntax args)))) + ; need lambda here... + (values 'define-form (wrap (syntax name) w mod) + (decorate-source + (cons (syntax lambda) (wrap (syntax (args e1 e2 ...)) w mod)) + s) + empty-wrap s mod)) + ((_ name) + (id? (syntax name)) + (values 'define-form (wrap (syntax name) w mod) + (syntax (if #f #f)) + empty-wrap s mod)))) + ((define-syntax) + (syntax-case e () + ((_ name val) + (id? (syntax name)) + (values 'define-syntax-form (syntax name) + (syntax val) w s mod)))) + (else + (values 'call #f e w s mod))))))) ((syntax-object? e) - ;; s can't be valid source if we've unwrapped (syntax-type (syntax-object-expression e) r (join-wraps w (syntax-object-wrap e)) - no-source rib)) - ((annotation? e) - (syntax-type (annotation-expression e) r w (annotation-source e) rib)) - ((self-evaluating? e) (values 'constant #f e w s)) - (else (values 'other #f e w s))))) + s rib (or (syntax-object-module e) mod) for-car?)) + ((self-evaluating? e) (values 'constant #f e w s mod)) + (else (values 'other #f e w s mod))))) (define chi-top - (lambda (e r w m esew) + (lambda (e r w m esew mod) (define-syntax eval-if-c&e (syntax-rules () - ((_ m e) + ((_ m e mod) (let ((x e)) - (if (eq? m 'c&e) (top-level-eval-hook x)) + (if (eq? m 'c&e) (top-level-eval-hook x mod)) x)))) (call-with-values - (lambda () (syntax-type e r w no-source #f)) - (lambda (type value e w s) + (lambda () (syntax-type e r w (source-annotation e) #f mod #f)) + (lambda (type value e w s mod) (case type ((begin-form) (syntax-case e () ((_) (chi-void)) ((_ e1 e2 ...) - (chi-top-sequence (syntax (e1 e2 ...)) r w s m esew)))) + (chi-top-sequence (syntax (e1 e2 ...)) r w s m esew mod)))) ((local-syntax-form) - (chi-local-syntax value e r w s - (lambda (body r w s) - (chi-top-sequence body r w s m esew)))) + (chi-local-syntax value e r w s mod + (lambda (body r w s mod) + (chi-top-sequence body r w s m esew mod)))) ((eval-when-form) (syntax-case e () ((_ (x ...) e1 e2 ...) @@ -1018,19 +1153,20 @@ (cond ((eq? m 'e) (if (memq 'eval when-list) - (chi-top-sequence body r w s 'e '(eval)) + (chi-top-sequence body r w s 'e '(eval) mod) (chi-void))) ((memq 'load when-list) (if (or (memq 'compile when-list) (and (eq? m 'c&e) (memq 'eval when-list))) - (chi-top-sequence body r w s 'c&e '(compile load)) + (chi-top-sequence body r w s 'c&e '(compile load) mod) (if (memq m '(c c&e)) - (chi-top-sequence body r w s 'c '(load)) + (chi-top-sequence body r w s 'c '(load) mod) (chi-void)))) ((or (memq 'compile when-list) (and (eq? m 'c&e) (memq 'eval when-list))) (top-level-eval-hook - (chi-top-sequence body r w s 'e '(eval))) + (chi-top-sequence body r w s 'e '(eval) mod) + mod) (chi-void)) (else (chi-void))))))) ((define-syntax-form) @@ -1038,93 +1174,118 @@ (case m ((c) (if (memq 'compile esew) - (let ((e (chi-install-global n (chi e r w)))) - (top-level-eval-hook e) + (let ((e (chi-install-global n (chi e r w mod)))) + (top-level-eval-hook e mod) (if (memq 'load esew) e (chi-void))) (if (memq 'load esew) - (chi-install-global n (chi e r w)) + (chi-install-global n (chi e r w mod)) (chi-void)))) ((c&e) - (let ((e (chi-install-global n (chi e r w)))) - (top-level-eval-hook e) + (let ((e (chi-install-global n (chi e r w mod)))) + (top-level-eval-hook e mod) e)) (else (if (memq 'eval esew) (top-level-eval-hook - (chi-install-global n (chi e r w)))) + (chi-install-global n (chi e r w mod)) + mod)) (chi-void))))) ((define-form) (let* ((n (id-var-name value w)) - (type (binding-type (lookup n r)))) + (type (binding-type (lookup n r mod)))) (case type - ((global) + ((global core macro module-ref) + ;; affect compile-time environment (once we have booted) + (if (and (not (module-local-variable (current-module) n)) + (current-module)) + (let ((old (module-variable (current-module) n))) + ;; use value of the same-named imported variable, if + ;; any + (module-define! (current-module) n + (if (variable? old) + (variable-ref old) + #f)))) (eval-if-c&e m - (build-global-definition s n (chi e r w)))) + (build-global-definition s n (chi e r w mod)) + mod)) ((displaced-lexical) - (syntax-error (wrap value w) "identifier out of context")) + (syntax-violation #f "identifier out of context" + e (wrap value w mod))) (else - (if (eq? type 'external-macro) - (eval-if-c&e m - (build-global-definition s n (chi e r w))) - (syntax-error (wrap value w) - "cannot define keyword at top level")))))) - (else (eval-if-c&e m (chi-expr type value e r w s)))))))) + (syntax-violation #f "cannot define keyword at top level" + e (wrap value w mod)))))) + (else (eval-if-c&e m (chi-expr type value e r w s mod) mod))))))) (define chi - (lambda (e r w) + (lambda (e r w mod) (call-with-values - (lambda () (syntax-type e r w no-source #f)) - (lambda (type value e w s) - (chi-expr type value e r w s))))) + (lambda () (syntax-type e r w (source-annotation e) #f mod #f)) + (lambda (type value e w s mod) + (chi-expr type value e r w s mod))))) (define chi-expr - (lambda (type value e r w s) + (lambda (type value e r w s mod) (case type ((lexical) - (build-lexical-reference 'value s value)) - ((core external-macro) (value e r w s)) + (build-lexical-reference 'value s e value)) + ((core core-form) + ;; apply transformer + (value e r w s mod)) + ((module-ref) + (call-with-values (lambda () (value e)) + ;; we could add a public? arg here + (lambda (id mod) (build-global-reference s id mod)))) ((lexical-call) (chi-application - (build-lexical-reference 'fun (source-annotation (car e)) value) - e r w s)) + (build-lexical-reference 'fun (source-annotation (car e)) + (car e) value) + e r w s mod)) ((global-call) (chi-application - (build-global-reference (source-annotation (car e)) value) - e r w s)) - ((constant) (build-data s (strip (source-wrap e w s) empty-wrap))) - ((global) (build-global-reference s value)) - ((call) (chi-application (chi (car e) r w) e r w s)) + (build-global-reference (source-annotation (car e)) + (if (syntax-object? value) + (syntax-object-expression value) + value) + (if (syntax-object? value) + (syntax-object-module value) + mod)) + e r w s mod)) + ((constant) (build-data s (strip (source-wrap e w s mod) empty-wrap))) + ((global) (build-global-reference s value mod)) + ((call) (chi-application (chi (car e) r w mod) e r w s mod)) ((begin-form) (syntax-case e () - ((_ e1 e2 ...) (chi-sequence (syntax (e1 e2 ...)) r w s)))) + ((_ e1 e2 ...) (chi-sequence (syntax (e1 e2 ...)) r w s mod)))) ((local-syntax-form) - (chi-local-syntax value e r w s chi-sequence)) + (chi-local-syntax value e r w s mod chi-sequence)) ((eval-when-form) (syntax-case e () ((_ (x ...) e1 e2 ...) (let ((when-list (chi-when-list e (syntax (x ...)) w))) (if (memq 'eval when-list) - (chi-sequence (syntax (e1 e2 ...)) r w s) + (chi-sequence (syntax (e1 e2 ...)) r w s mod) (chi-void)))))) ((define-form define-syntax-form) - (syntax-error (wrap value w) "invalid context for definition of")) + (syntax-violation #f "definition in expression context" + e (wrap value w mod))) ((syntax) - (syntax-error (source-wrap e w s) - "reference to pattern variable outside syntax form")) + (syntax-violation #f "reference to pattern variable outside syntax form" + (source-wrap e w s mod))) ((displaced-lexical) - (syntax-error (source-wrap e w s) - "reference to identifier outside its scope")) - (else (syntax-error (source-wrap e w s)))))) + (syntax-violation #f "reference to identifier outside its scope" + (source-wrap e w s mod))) + (else (syntax-violation #f "unexpected syntax" + (source-wrap e w s mod)))))) (define chi-application - (lambda (x e r w s) + (lambda (x e r w s mod) (syntax-case e () ((e0 e1 ...) (build-application s x - (map (lambda (e) (chi e r w)) (syntax (e1 ...)))))))) + (map (lambda (e) (chi e r w mod)) (syntax (e1 ...)))))))) (define chi-macro - (lambda (p e r w rib) + (lambda (p e r w rib mod) (define rebuild-macro-output (lambda (x m) (cond ((pair? x) @@ -1133,14 +1294,27 @@ ((syntax-object? x) (let ((w (syntax-object-wrap x))) (let ((ms (wrap-marks w)) (s (wrap-subst w))) - (make-syntax-object (syntax-object-expression x) - (if (and (pair? ms) (eq? (car ms) the-anti-mark)) - (make-wrap (cdr ms) - (if rib (cons rib (cdr s)) (cdr s))) - (make-wrap (cons m ms) - (if rib - (cons rib (cons 'shift s)) - (cons 'shift s)))))))) + (if (and (pair? ms) (eq? (car ms) the-anti-mark)) + ;; output is from original text + (make-syntax-object + (syntax-object-expression x) + (make-wrap (cdr ms) (if rib (cons rib (cdr s)) (cdr s))) + (syntax-object-module x)) + ;; output introduced by macro + (make-syntax-object + (syntax-object-expression x) + (make-wrap (cons m ms) + (if rib + (cons rib (cons 'shift s)) + (cons 'shift s))) + (let ((pmod (procedure-module p))) + (if pmod + ;; hither the hygiene + (cons 'hygiene (module-name pmod)) + ;; but it's possible for the proc to have + ;; no mod, if it was made before modules + ;; were booted + '(hygiene guile)))))))) ((vector? x) (let* ((n (vector-length x)) (v (make-vector n))) (do ((i 0 (fx+ i 1))) @@ -1148,9 +1322,10 @@ (vector-set! v i (rebuild-macro-output (vector-ref x i) m))))) ((symbol? x) - (syntax-error x "encountered raw symbol in macro output")) + (syntax-violation #f "encountered raw symbol in macro output" + (source-wrap e w s mod) x)) (else x)))) - (rebuild-macro-output (p (wrap e (anti-mark w))) (new-mark)))) + (rebuild-macro-output (p (wrap e (anti-mark w) mod)) (new-mark)))) (define chi-body ;; In processing the forms of the body, we create a new, empty wrap. @@ -1191,34 +1366,36 @@ ;; into the body. ;; ;; outer-form is fully wrapped w/source - (lambda (body outer-form r w) + (lambda (body outer-form r w mod) (let* ((r (cons '("placeholder" . (placeholder)) r)) (ribcage (make-empty-ribcage)) (w (make-wrap (wrap-marks w) (cons ribcage (wrap-subst w))))) - (let parse ((body (map (lambda (x) (cons r (wrap x w))) body)) - (ids '()) (labels '()) (vars '()) (vals '()) (bindings '())) + (let parse ((body (map (lambda (x) (cons r (wrap x w mod))) body)) + (ids '()) (labels '()) + (var-ids '()) (vars '()) (vals '()) (bindings '())) (if (null? body) - (syntax-error outer-form "no expressions in body") + (syntax-violation #f "no expressions in body" outer-form) (let ((e (cdar body)) (er (caar body))) (call-with-values - (lambda () (syntax-type e er empty-wrap no-source ribcage)) - (lambda (type value e w s) + (lambda () (syntax-type e er empty-wrap (source-annotation er) ribcage mod #f)) + (lambda (type value e w s mod) (case type ((define-form) - (let ((id (wrap value w)) (label (gen-label))) + (let ((id (wrap value w mod)) (label (gen-label))) (let ((var (gen-var id))) (extend-ribcage! ribcage id label) (parse (cdr body) (cons id ids) (cons label labels) - (cons var vars) (cons (cons er (wrap e w)) vals) + (cons id var-ids) + (cons var vars) (cons (cons er (wrap e w mod)) vals) (cons (make-binding 'lexical var) bindings))))) ((define-syntax-form) - (let ((id (wrap value w)) (label (gen-label))) + (let ((id (wrap value w mod)) (label (gen-label))) (extend-ribcage! ribcage id label) (parse (cdr body) (cons id ids) (cons label labels) - vars vals - (cons (make-binding 'macro (cons er (wrap e w))) + var-ids vars vals + (cons (make-binding 'macro (cons er (wrap e w mod))) bindings)))) ((begin-form) (syntax-case e () @@ -1226,29 +1403,30 @@ (parse (let f ((forms (syntax (e1 ...)))) (if (null? forms) (cdr body) - (cons (cons er (wrap (car forms) w)) + (cons (cons er (wrap (car forms) w mod)) (f (cdr forms))))) - ids labels vars vals bindings)))) + ids labels var-ids vars vals bindings)))) ((local-syntax-form) - (chi-local-syntax value e er w s - (lambda (forms er w s) + (chi-local-syntax value e er w s mod + (lambda (forms er w s mod) (parse (let f ((forms forms)) (if (null? forms) (cdr body) - (cons (cons er (wrap (car forms) w)) + (cons (cons er (wrap (car forms) w mod)) (f (cdr forms))))) - ids labels vars vals bindings)))) + ids labels var-ids vars vals bindings)))) (else ; found a non-definition (if (null? ids) (build-sequence no-source (map (lambda (x) - (chi (cdr x) (car x) empty-wrap)) - (cons (cons er (source-wrap e w s)) + (chi (cdr x) (car x) empty-wrap mod)) + (cons (cons er (source-wrap e w s mod)) (cdr body)))) (begin (if (not (valid-bound-ids? ids)) - (syntax-error outer-form - "invalid or duplicate identifier in definition")) + (syntax-violation + #f "invalid or duplicate identifier in definition" + outer-form)) (let loop ((bs bindings) (er-cache #f) (r-cache #f)) (if (not (null? bs)) (let* ((b (car bs))) @@ -1260,58 +1438,72 @@ (macros-only-env er)))) (set-cdr! b (eval-local-transformer - (chi (cddr b) r-cache empty-wrap))) + (chi (cddr b) r-cache empty-wrap mod) + mod)) (loop (cdr bs) er r-cache)) (loop (cdr bs) er-cache r-cache))))) (set-cdr! r (extend-env labels bindings (cdr r))) (build-letrec no-source + (map syntax->datum var-ids) vars (map (lambda (x) - (chi (cdr x) (car x) empty-wrap)) + (chi (cdr x) (car x) empty-wrap mod)) vals) (build-sequence no-source (map (lambda (x) - (chi (cdr x) (car x) empty-wrap)) - (cons (cons er (source-wrap e w s)) + (chi (cdr x) (car x) empty-wrap mod)) + (cons (cons er (source-wrap e w s mod)) (cdr body))))))))))))))))) (define chi-lambda-clause - (lambda (e c r w k) + (lambda (e docstring c r w mod k) (syntax-case c () + ((args doc e1 e2 ...) + (and (string? (syntax->datum (syntax doc))) (not docstring)) + (chi-lambda-clause e (syntax doc) (syntax (args e1 e2 ...)) r w mod k)) (((id ...) e1 e2 ...) (let ((ids (syntax (id ...)))) (if (not (valid-bound-ids? ids)) - (syntax-error e "invalid parameter list in") + (syntax-violation 'lambda "invalid parameter list" e) (let ((labels (gen-labels ids)) (new-vars (map gen-var ids))) - (k new-vars + (k (map syntax->datum ids) + new-vars + (and docstring (syntax->datum docstring)) (chi-body (syntax (e1 e2 ...)) e (extend-var-env labels new-vars r) - (make-binding-wrap ids labels w))))))) + (make-binding-wrap ids labels w) + mod)))))) ((ids e1 e2 ...) (let ((old-ids (lambda-var-list (syntax ids)))) (if (not (valid-bound-ids? old-ids)) - (syntax-error e "invalid parameter list in") + (syntax-violation 'lambda "invalid parameter list" e) (let ((labels (gen-labels old-ids)) (new-vars (map gen-var old-ids))) - (k (let f ((ls1 (cdr new-vars)) (ls2 (car new-vars))) + (k (let f ((ls1 (cdr old-ids)) (ls2 (car old-ids))) + (if (null? ls1) + (syntax->datum ls2) + (f (cdr ls1) (cons (syntax->datum (car ls1)) ls2)))) + (let f ((ls1 (cdr new-vars)) (ls2 (car new-vars))) (if (null? ls1) ls2 (f (cdr ls1) (cons (car ls1) ls2)))) + (and docstring (syntax->datum docstring)) (chi-body (syntax (e1 e2 ...)) e (extend-var-env labels new-vars r) - (make-binding-wrap old-ids labels w))))))) - (_ (syntax-error e))))) + (make-binding-wrap old-ids labels w) + mod)))))) + (_ (syntax-violation 'lambda "bad lambda" e))))) (define chi-local-syntax - (lambda (rec? e r w s k) + (lambda (rec? e r w s mod k) (syntax-case e () ((_ ((id val) ...) e1 e2 ...) (let ((ids (syntax (id ...)))) (if (not (valid-bound-ids? ids)) - (syntax-error e "duplicate bound keyword in") + (syntax-violation #f "duplicate bound keyword" e) (let ((labels (gen-labels ids))) (let ((new-w (make-binding-wrap ids labels w))) (k (syntax (e1 e2 ...)) @@ -1321,23 +1513,27 @@ (trans-r (macros-only-env r))) (map (lambda (x) (make-binding 'macro - (eval-local-transformer (chi x trans-r w)))) + (eval-local-transformer + (chi x trans-r w mod) + mod))) (syntax (val ...)))) r) new-w - s)))))) - (_ (syntax-error (source-wrap e w s)))))) + s + mod)))))) + (_ (syntax-violation #f "bad local syntax definition" + (source-wrap e w s mod)))))) (define eval-local-transformer - (lambda (expanded) - (let ((p (local-eval-hook expanded))) + (lambda (expanded mod) + (let ((p (local-eval-hook expanded mod))) (if (procedure? p) p - (syntax-error p "nonprocedure transformer"))))) + (syntax-violation #f "nonprocedure transformer" p))))) (define chi-void (lambda () - (build-application no-source (build-primref no-source 'void) '()))) + (build-void no-source))) (define ellipsis? (lambda (x) @@ -1346,32 +1542,8 @@ ;;; data -;;; strips all annotations from potentially circular reader output - -(define strip-annotation - (lambda (x parent) - (cond - ((pair? x) - (let ((new (cons #f #f))) - (if parent (set-annotation-stripped! parent new)) - (set-car! new (strip-annotation (car x) #f)) - (set-cdr! new (strip-annotation (cdr x) #f)) - new)) - ((annotation? x) - (or (annotation-stripped x) - (strip-annotation (annotation-expression x) x))) - ((vector? x) - (let ((new (make-vector (vector-length x)))) - (if parent (set-annotation-stripped! parent new)) - (let loop ((i (- (vector-length x) 1))) - (unless (fx< i 0) - (vector-set! new i (strip-annotation (vector-ref x i) #f)) - (loop (fx- i 1)))) - new)) - (else x)))) - -;;; strips syntax-objects down to top-wrap; if top-wrap is layered directly -;;; on an annotation, strips the annotation as well. +;;; strips syntax-objects down to top-wrap +;;; ;;; since only the head of a list is annotated by the reader, not each pair ;;; in the spine, we also check for pairs whose cars are annotated in case ;;; we've been passed the cdr of an annotated list @@ -1379,46 +1551,40 @@ (define strip (lambda (x w) (if (top-marked? w) - (if (or (annotation? x) (and (pair? x) (annotation? (car x)))) - (strip-annotation x #f) - x) + x (let f ((x x)) (cond - ((syntax-object? x) - (strip (syntax-object-expression x) (syntax-object-wrap x))) - ((pair? x) - (let ((a (f (car x))) (d (f (cdr x)))) - (if (and (eq? a (car x)) (eq? d (cdr x))) - x - (cons a d)))) - ((vector? x) - (let ((old (vector->list x))) - (let ((new (map f old))) - (if (andmap eq? old new) x (list->vector new))))) - (else x)))))) + ((syntax-object? x) + (strip (syntax-object-expression x) (syntax-object-wrap x))) + ((pair? x) + (let ((a (f (car x))) (d (f (cdr x)))) + (if (and (eq? a (car x)) (eq? d (cdr x))) + x + (cons a d)))) + ((vector? x) + (let ((old (vector->list x))) + (let ((new (map f old))) + (if (and-map* eq? old new) x (list->vector new))))) + (else x)))))) ;;; lexical variables (define gen-var (lambda (id) (let ((id (if (syntax-object? id) (syntax-object-expression id) id))) - (if (annotation? id) - (build-lexical-var (annotation-source id) (annotation-expression id)) - (build-lexical-var no-source id))))) + (build-lexical-var no-source id)))) (define lambda-var-list (lambda (vars) (let lvl ((vars vars) (ls '()) (w empty-wrap)) (cond - ((pair? vars) (lvl (cdr vars) (cons (wrap (car vars) w) ls) w)) - ((id? vars) (cons (wrap vars w) ls)) + ((pair? vars) (lvl (cdr vars) (cons (wrap (car vars) w #f) ls) w)) + ((id? vars) (cons (wrap vars w #f) ls)) ((null? vars) ls) ((syntax-object? vars) (lvl (syntax-object-expression vars) ls (join-wraps w (syntax-object-wrap vars)))) - ((annotation? vars) - (lvl (annotation-expression vars) ls w)) ; include anything else to be caught by subsequent error ; checking (else (cons vars ls)))))) @@ -1429,46 +1595,52 @@ (global-extend 'local-syntax 'let-syntax #f) (global-extend 'core 'fluid-let-syntax - (lambda (e r w s) + (lambda (e r w s mod) (syntax-case e () ((_ ((var val) ...) e1 e2 ...) (valid-bound-ids? (syntax (var ...))) (let ((names (map (lambda (x) (id-var-name x w)) (syntax (var ...))))) (for-each (lambda (id n) - (case (binding-type (lookup n r)) + (case (binding-type (lookup n r mod)) ((displaced-lexical) - (syntax-error (source-wrap id w s) - "identifier out of context")))) + (syntax-violation 'fluid-let-syntax + "identifier out of context" + e + (source-wrap id w s mod))))) (syntax (var ...)) names) (chi-body (syntax (e1 e2 ...)) - (source-wrap e w s) + (source-wrap e w s mod) (extend-env names (let ((trans-r (macros-only-env r))) (map (lambda (x) (make-binding 'macro - (eval-local-transformer (chi x trans-r w)))) + (eval-local-transformer (chi x trans-r w mod) + mod))) (syntax (val ...)))) r) - w))) - (_ (syntax-error (source-wrap e w s)))))) + w + mod))) + (_ (syntax-violation 'fluid-let-syntax "bad syntax" + (source-wrap e w s mod)))))) (global-extend 'core 'quote - (lambda (e r w s) + (lambda (e r w s mod) (syntax-case e () ((_ e) (build-data s (strip (syntax e) w))) - (_ (syntax-error (source-wrap e w s)))))) + (_ (syntax-violation 'quote "bad syntax" + (source-wrap e w s mod)))))) (global-extend 'core 'syntax (let () (define gen-syntax - (lambda (src e r maps ellipsis?) + (lambda (src e r maps ellipsis? mod) (if (id? e) (let ((label (id-var-name e empty-wrap))) - (let ((b (lookup label r))) + (let ((b (lookup label r mod))) (if (eq? (binding-type b) 'syntax) (call-with-values (lambda () @@ -1476,12 +1648,12 @@ (gen-ref src (car var.lev) (cdr var.lev) maps))) (lambda (var maps) (values `(ref ,var) maps))) (if (ellipsis? e) - (syntax-error src "misplaced ellipsis in syntax form") + (syntax-violation 'syntax "misplaced ellipsis" src) (values `(quote ,e) maps))))) (syntax-case e () ((dots e) (ellipsis? (syntax dots)) - (gen-syntax src (syntax e) r maps (lambda (x) #f))) + (gen-syntax src (syntax e) r maps (lambda (x) #f) mod)) ((x dots . y) ; this could be about a dozen lines of code, except that we ; choose to handle (syntax (x ... ...)) forms @@ -1491,11 +1663,11 @@ (call-with-values (lambda () (gen-syntax src (syntax x) r - (cons '() maps) ellipsis?)) + (cons '() maps) ellipsis? mod)) (lambda (x maps) (if (null? (car maps)) - (syntax-error src - "extra ellipsis in syntax form") + (syntax-violation 'syntax "extra ellipsis" + src) (values (gen-map x (car maps)) (cdr maps)))))))) (syntax-case y () @@ -1507,12 +1679,11 @@ (lambda () (k (cons '() maps))) (lambda (x maps) (if (null? (car maps)) - (syntax-error src - "extra ellipsis in syntax form") + (syntax-violation 'syntax "extra ellipsis" src) (values (gen-mappend x (car maps)) (cdr maps)))))))) (_ (call-with-values - (lambda () (gen-syntax src y r maps ellipsis?)) + (lambda () (gen-syntax src y r maps ellipsis? mod)) (lambda (y maps) (call-with-values (lambda () (k maps)) @@ -1520,15 +1691,15 @@ (values (gen-append x y) maps))))))))) ((x . y) (call-with-values - (lambda () (gen-syntax src (syntax x) r maps ellipsis?)) + (lambda () (gen-syntax src (syntax x) r maps ellipsis? mod)) (lambda (x maps) (call-with-values - (lambda () (gen-syntax src (syntax y) r maps ellipsis?)) + (lambda () (gen-syntax src (syntax y) r maps ellipsis? mod)) (lambda (y maps) (values (gen-cons x y) maps)))))) (#(e1 e2 ...) (call-with-values (lambda () - (gen-syntax src (syntax (e1 e2 ...)) r maps ellipsis?)) + (gen-syntax src (syntax (e1 e2 ...)) r maps ellipsis? mod)) (lambda (e maps) (values (gen-vector e) maps)))) (_ (values `(quote ,e) maps)))))) @@ -1537,7 +1708,7 @@ (if (fx= level 0) (values var maps) (if (null? maps) - (syntax-error src "missing ellipsis in syntax form") + (syntax-violation 'syntax "missing ellipsis" src) (call-with-values (lambda () (gen-ref src var (fx- level 1) (cdr maps))) (lambda (outer-var outer-maps) @@ -1563,7 +1734,7 @@ ; identity map equivalence: ; (map (lambda (x) x) y) == y (car actuals)) - ((andmap + ((and-map (lambda (x) (and (eq? (car x) 'ref) (memq (cadr x) formals))) (cdr e)) ; eta map equivalence: @@ -1603,110 +1774,158 @@ (define regen (lambda (x) (case (car x) - ((ref) (build-lexical-reference 'value no-source (cadr x))) + ((ref) (build-lexical-reference 'value no-source (cadr x) (cadr x))) ((primitive) (build-primref no-source (cadr x))) ((quote) (build-data no-source (cadr x))) - ((lambda) (build-lambda no-source (cadr x) (regen (caddr x)))) - ((map) (let ((ls (map regen (cdr x)))) - (build-application no-source - (if (fx= (length ls) 2) - (build-primref no-source 'map) - ; really need to do our own checking here - (build-primref no-source 2 'map)) ; require error check - ls))) + ((lambda) (build-lambda no-source (cadr x) (cadr x) #f (regen (caddr x)))) (else (build-application no-source (build-primref no-source (car x)) (map regen (cdr x))))))) - (lambda (e r w s) - (let ((e (source-wrap e w s))) + (lambda (e r w s mod) + (let ((e (source-wrap e w s mod))) (syntax-case e () ((_ x) (call-with-values - (lambda () (gen-syntax e (syntax x) r '() ellipsis?)) + (lambda () (gen-syntax e (syntax x) r '() ellipsis? mod)) (lambda (e maps) (regen e)))) - (_ (syntax-error e))))))) + (_ (syntax-violation 'syntax "bad `syntax' form" e))))))) (global-extend 'core 'lambda - (lambda (e r w s) + (lambda (e r w s mod) (syntax-case e () ((_ . c) - (chi-lambda-clause (source-wrap e w s) (syntax c) r w - (lambda (vars body) (build-lambda s vars body))))))) + (chi-lambda-clause (source-wrap e w s mod) #f (syntax c) r w mod + (lambda (names vars docstring body) + (build-lambda s names vars docstring body))))))) (global-extend 'core 'let (let () - (define (chi-let e r w s constructor ids vals exps) + (define (chi-let e r w s mod constructor ids vals exps) (if (not (valid-bound-ids? ids)) - (syntax-error e "duplicate bound variable in") + (syntax-violation 'let "duplicate bound variable" e) (let ((labels (gen-labels ids)) (new-vars (map gen-var ids))) (let ((nw (make-binding-wrap ids labels w)) (nr (extend-var-env labels new-vars r))) (constructor s + (map syntax->datum ids) new-vars - (map (lambda (x) (chi x r w)) vals) - (chi-body exps (source-wrap e nw s) nr nw)))))) - (lambda (e r w s) + (map (lambda (x) (chi x r w mod)) vals) + (chi-body exps (source-wrap e nw s mod) + nr nw mod)))))) + (lambda (e r w s mod) (syntax-case e () ((_ ((id val) ...) e1 e2 ...) - (chi-let e r w s + (and-map id? (syntax (id ...))) + (chi-let e r w s mod build-let (syntax (id ...)) (syntax (val ...)) (syntax (e1 e2 ...)))) ((_ f ((id val) ...) e1 e2 ...) - (id? (syntax f)) - (chi-let e r w s + (and (id? (syntax f)) (and-map id? (syntax (id ...)))) + (chi-let e r w s mod build-named-let (syntax (f id ...)) (syntax (val ...)) (syntax (e1 e2 ...)))) - (_ (syntax-error (source-wrap e w s))))))) + (_ (syntax-violation 'let "bad let" (source-wrap e w s mod))))))) (global-extend 'core 'letrec - (lambda (e r w s) + (lambda (e r w s mod) (syntax-case e () ((_ ((id val) ...) e1 e2 ...) + (and-map id? (syntax (id ...))) (let ((ids (syntax (id ...)))) (if (not (valid-bound-ids? ids)) - (syntax-error e "duplicate bound variable in") + (syntax-violation 'letrec "duplicate bound variable" e) (let ((labels (gen-labels ids)) (new-vars (map gen-var ids))) (let ((w (make-binding-wrap ids labels w)) (r (extend-var-env labels new-vars r))) (build-letrec s + (map syntax->datum ids) new-vars - (map (lambda (x) (chi x r w)) (syntax (val ...))) - (chi-body (syntax (e1 e2 ...)) (source-wrap e w s) r w))))))) - (_ (syntax-error (source-wrap e w s)))))) + (map (lambda (x) (chi x r w mod)) (syntax (val ...))) + (chi-body (syntax (e1 e2 ...)) + (source-wrap e w s mod) r w mod))))))) + (_ (syntax-violation 'letrec "bad letrec" (source-wrap e w s mod)))))) (global-extend 'core 'set! - (lambda (e r w s) + (lambda (e r w s mod) (syntax-case e () ((_ id val) (id? (syntax id)) - (let ((val (chi (syntax val) r w)) + (let ((val (chi (syntax val) r w mod)) (n (id-var-name (syntax id) w))) - (let ((b (lookup n r))) + (let ((b (lookup n r mod))) (case (binding-type b) ((lexical) - (build-lexical-assignment s (binding-value b) val)) - ((global) (build-global-assignment s n val)) + (build-lexical-assignment s + (syntax->datum (syntax id)) + (binding-value b) + val)) + ((global) (build-global-assignment s n val mod)) ((displaced-lexical) - (syntax-error (wrap (syntax id) w) - "identifier out of context")) - (else (syntax-error (source-wrap e w s))))))) - ((_ (getter arg ...) val) - (build-application s - (chi (syntax (setter getter)) r w) - (map (lambda (e) (chi e r w)) - (syntax (arg ... val))))) - (_ (syntax-error (source-wrap e w s)))))) + (syntax-violation 'set! "identifier out of context" + (wrap (syntax id) w mod))) + (else (syntax-violation 'set! "bad set!" + (source-wrap e w s mod))))))) + ((_ (head tail ...) val) + (call-with-values + (lambda () (syntax-type (syntax head) r empty-wrap no-source #f mod #t)) + (lambda (type value ee ww ss modmod) + (case type + ((module-ref) + (let ((val (chi (syntax val) r w mod))) + (call-with-values (lambda () (value (syntax (head tail ...)))) + (lambda (id mod) + (build-global-assignment s id val mod))))) + (else + (build-application s + (chi (syntax (setter head)) r w mod) + (map (lambda (e) (chi e r w mod)) + (syntax (tail ... val))))))))) + (_ (syntax-violation 'set! "bad set!" (source-wrap e w s mod)))))) + +(global-extend 'module-ref '@ + (lambda (e) + (syntax-case e () + ((_ (mod ...) id) + (and (and-map id? (syntax (mod ...))) (id? (syntax id))) + (values (syntax->datum (syntax id)) + (syntax->datum + (syntax (public mod ...)))))))) + +(global-extend 'module-ref '@@ + (lambda (e) + (syntax-case e () + ((_ (mod ...) id) + (and (and-map id? (syntax (mod ...))) (id? (syntax id))) + (values (syntax->datum (syntax id)) + (syntax->datum + (syntax (private mod ...)))))))) + +(global-extend 'core 'if + (lambda (e r w s mod) + (syntax-case e () + ((_ test then) + (build-conditional + s + (chi (syntax test) r w mod) + (chi (syntax then) r w mod) + (build-void no-source))) + ((_ test then else) + (build-conditional + s + (chi (syntax test) r w mod) + (chi (syntax then) r w mod) + (chi (syntax else) r w mod)))))) (global-extend 'begin 'begin '()) @@ -1720,7 +1939,7 @@ (let () (define convert-pattern ; accepts pattern & keys - ; returns syntax-dispatch pattern & ids + ; returns $sc-dispatch pattern & ids (lambda (pattern keys) (let cvt ((p pattern) (n 0) (ids '())) (if (id? p) @@ -1751,102 +1970,111 @@ (x (values (vector 'atom (strip p empty-wrap)) ids))))))) (define build-dispatch-call - (lambda (pvars exp y r) + (lambda (pvars exp y r mod) (let ((ids (map car pvars)) (levels (map cdr pvars))) (let ((labels (gen-labels ids)) (new-vars (map gen-var ids))) (build-application no-source (build-primref no-source 'apply) - (list (build-lambda no-source new-vars + (list (build-lambda no-source (map syntax->datum ids) new-vars #f (chi exp - (extend-env - labels - (map (lambda (var level) - (make-binding 'syntax `(,var . ,level))) - new-vars - (map cdr pvars)) - r) - (make-binding-wrap ids labels empty-wrap))) + (extend-env + labels + (map (lambda (var level) + (make-binding 'syntax `(,var . ,level))) + new-vars + (map cdr pvars)) + r) + (make-binding-wrap ids labels empty-wrap) + mod)) y)))))) (define gen-clause - (lambda (x keys clauses r pat fender exp) + (lambda (x keys clauses r pat fender exp mod) (call-with-values (lambda () (convert-pattern pat keys)) (lambda (p pvars) (cond ((not (distinct-bound-ids? (map car pvars))) - (syntax-error pat - "duplicate pattern variable in syntax-case pattern")) - ((not (andmap (lambda (x) (not (ellipsis? (car x)))) pvars)) - (syntax-error pat - "misplaced ellipsis in syntax-case pattern")) + (syntax-violation 'syntax-case "duplicate pattern variable" pat)) + ((not (and-map (lambda (x) (not (ellipsis? (car x)))) pvars)) + (syntax-violation 'syntax-case "misplaced ellipsis" pat)) (else (let ((y (gen-var 'tmp))) ; fat finger binding and references to temp variable y (build-application no-source - (build-lambda no-source (list y) - (let ((y (build-lexical-reference 'value no-source y))) + (build-lambda no-source (list 'tmp) (list y) #f + (let ((y (build-lexical-reference 'value no-source + 'tmp y))) (build-conditional no-source (syntax-case fender () (#t y) (_ (build-conditional no-source y - (build-dispatch-call pvars fender y r) + (build-dispatch-call pvars fender y r mod) (build-data no-source #f)))) - (build-dispatch-call pvars exp y r) - (gen-syntax-case x keys clauses r)))) + (build-dispatch-call pvars exp y r mod) + (gen-syntax-case x keys clauses r mod)))) (list (if (eq? p 'any) (build-application no-source (build-primref no-source 'list) (list x)) (build-application no-source - (build-primref no-source 'syntax-dispatch) + (build-primref no-source '$sc-dispatch) (list x (build-data no-source p))))))))))))) (define gen-syntax-case - (lambda (x keys clauses r) + (lambda (x keys clauses r mod) (if (null? clauses) (build-application no-source - (build-primref no-source 'syntax-error) - (list x)) + (build-primref no-source 'syntax-violation) + (list (build-data no-source #f) + (build-data no-source + "source expression failed to match any pattern") + x)) (syntax-case (car clauses) () ((pat exp) (if (and (id? (syntax pat)) - (andmap (lambda (x) (not (free-id=? (syntax pat) x))) - (cons (syntax (... ...)) keys))) + (and-map (lambda (x) (not (free-id=? (syntax pat) x))) + (cons (syntax (... ...)) keys))) (let ((labels (list (gen-label))) (var (gen-var (syntax pat)))) (build-application no-source - (build-lambda no-source (list var) + (build-lambda no-source + (list (syntax->datum (syntax pat))) (list var) + #f (chi (syntax exp) (extend-env labels (list (make-binding 'syntax `(,var . 0))) r) (make-binding-wrap (syntax (pat)) - labels empty-wrap))) + labels empty-wrap) + mod)) (list x))) (gen-clause x keys (cdr clauses) r - (syntax pat) #t (syntax exp)))) + (syntax pat) #t (syntax exp) mod))) ((pat fender exp) (gen-clause x keys (cdr clauses) r - (syntax pat) (syntax fender) (syntax exp))) - (_ (syntax-error (car clauses) "invalid syntax-case clause")))))) + (syntax pat) (syntax fender) (syntax exp) mod)) + (_ (syntax-violation 'syntax-case "invalid clause" + (car clauses))))))) - (lambda (e r w s) - (let ((e (source-wrap e w s))) + (lambda (e r w s mod) + (let ((e (source-wrap e w s mod))) (syntax-case e () ((_ val (key ...) m ...) - (if (andmap (lambda (x) (and (id? x) (not (ellipsis? x)))) - (syntax (key ...))) + (if (and-map (lambda (x) (and (id? x) (not (ellipsis? x)))) + (syntax (key ...))) (let ((x (gen-var 'tmp))) ; fat finger binding and references to temp variable x (build-application s - (build-lambda no-source (list x) - (gen-syntax-case (build-lexical-reference 'value no-source x) + (build-lambda no-source (list 'tmp) (list x) #f + (gen-syntax-case (build-lexical-reference 'value no-source + 'tmp x) (syntax (key ...)) (syntax (m ...)) - r)) - (list (chi (syntax val) r empty-wrap)))) - (syntax-error e "invalid literals list in")))))))) + r + mod)) + (list (chi (syntax val) r empty-wrap mod)))) + (syntax-violation 'syntax-case "invalid literals list" e)))))))) ;;; The portable sc-expand seeds chi-top's mode m with 'e (for ;;; evaluating) and esew (which stands for "eval syntax expanders @@ -1858,34 +2086,27 @@ ;;; expanded, and the expanded definitions are also residualized into ;;; the object file if we are compiling a file. (set! sc-expand - (let ((m 'e) (esew '(eval))) - (lambda (x) - (if (and (pair? x) (equal? (car x) noexpand)) - (cadr x) - (chi-top x null-env top-wrap m esew))))) - -(set! sc-expand3 - (let ((m 'e) (esew '(eval))) - (lambda (x . rest) - (if (and (pair? x) (equal? (car x) noexpand)) - (cadr x) - (chi-top x - null-env - top-wrap - (if (null? rest) m (car rest)) - (if (or (null? rest) (null? (cdr rest))) - esew - (cadr rest))))))) + (lambda (x . rest) + (if (and (pair? x) (equal? (car x) noexpand)) + (cadr x) + (let ((m (if (null? rest) 'e (car rest))) + (esew (if (or (null? rest) (null? (cdr rest))) + '(eval) + (cadr rest)))) + (with-fluid* *mode* m + (lambda () + (chi-top x null-env top-wrap m esew + (cons 'hygiene (module-name (current-module)))))))))) (set! identifier? (lambda (x) (nonsymbol-id? x))) -(set! datum->syntax-object +(set! datum->syntax (lambda (id datum) - (make-syntax-object datum (syntax-object-wrap id)))) + (make-syntax-object datum (syntax-object-wrap id) #f))) -(set! syntax-object->datum +(set! syntax->datum ; accepts any object, since syntax objects may consist partially ; or entirely of unwrapped, nonsymbolic data (lambda (x) @@ -1894,7 +2115,7 @@ (set! generate-temporaries (lambda (ls) (arg-check list? ls 'generate-temporaries) - (map (lambda (x) (wrap (gensym-hook) top-wrap)) ls))) + (map (lambda (x) (wrap (gensym-hook) top-wrap #f)) ls))) (set! free-identifier=? (lambda (x y) @@ -1908,21 +2129,23 @@ (arg-check nonsymbol-id? y 'bound-identifier=?) (bound-id=? x y))) -(set! syntax-error - (lambda (object . messages) - (for-each (lambda (x) (arg-check string? x 'syntax-error)) messages) - (let ((message (if (null? messages) - "invalid syntax" - (apply string-append messages)))) - (error-hook #f message (strip object empty-wrap))))) +(set! syntax-violation + (lambda (who message form . subform) + (arg-check (lambda (x) (or (not x) (string? x) (symbol? x))) + who 'syntax-violation) + (arg-check string? message 'syntax-violation) + (scm-error 'syntax-error 'sc-expand + (string-append + (if who "~a: " "") + "~a " + (if (null? subform) "in ~a" "in subform `~s' of `~s'")) + (let ((tail (cons message + (map (lambda (x) (strip x empty-wrap)) + (append subform (list form)))))) + (if who (cons who tail) tail)) + #f))) -(set! install-global-transformer - (lambda (sym v) - (arg-check symbol? sym 'define-syntax) - (arg-check procedure? v 'define-syntax) - (global-extend 'macro sym v))) - -;;; syntax-dispatch expects an expression and a pattern. If the expression +;;; $sc-dispatch expects an expression and a pattern. If the expression ;;; matches the pattern a list of the matching expressions for each ;;; "any" is returned. Otherwise, #f is returned. (This use of #f will ;;; not work on r4rs implementations that violate the ieee requirement @@ -1947,35 +2170,33 @@ (let () (define match-each - (lambda (e p w) + (lambda (e p w mod) (cond - ((annotation? e) - (match-each (annotation-expression e) p w)) - ((pair? e) - (let ((first (match (car e) p w '()))) - (and first - (let ((rest (match-each (cdr e) p w))) - (and rest (cons first rest)))))) - ((null? e) '()) - ((syntax-object? e) - (match-each (syntax-object-expression e) - p - (join-wraps w (syntax-object-wrap e)))) - (else #f)))) + ((pair? e) + (let ((first (match (car e) p w '() mod))) + (and first + (let ((rest (match-each (cdr e) p w mod))) + (and rest (cons first rest)))))) + ((null? e) '()) + ((syntax-object? e) + (match-each (syntax-object-expression e) + p + (join-wraps w (syntax-object-wrap e)) + (syntax-object-module e))) + (else #f)))) (define match-each-any - (lambda (e w) + (lambda (e w mod) (cond - ((annotation? e) - (match-each-any (annotation-expression e) w)) - ((pair? e) - (let ((l (match-each-any (cdr e) w))) - (and l (cons (wrap (car e) w) l)))) - ((null? e) '()) - ((syntax-object? e) - (match-each-any (syntax-object-expression e) - (join-wraps w (syntax-object-wrap e)))) - (else #f)))) + ((pair? e) + (let ((l (match-each-any (cdr e) w mod))) + (and l (cons (wrap (car e) w mod) l)))) + ((null? e) '()) + ((syntax-object? e) + (match-each-any (syntax-object-expression e) + (join-wraps w (syntax-object-wrap e)) + mod)) + (else #f)))) (define match-empty (lambda (p r) @@ -1991,54 +2212,55 @@ ((vector) (match-empty (vector-ref p 1) r))))))) (define match* - (lambda (e p w r) + (lambda (e p w r mod) (cond ((null? p) (and (null? e) r)) ((pair? p) (and (pair? e) (match (car e) (car p) w - (match (cdr e) (cdr p) w r)))) + (match (cdr e) (cdr p) w r mod) + mod))) ((eq? p 'each-any) - (let ((l (match-each-any e w))) (and l (cons l r)))) + (let ((l (match-each-any e w mod))) (and l (cons l r)))) (else (case (vector-ref p 0) ((each) (if (null? e) (match-empty (vector-ref p 1) r) - (let ((l (match-each e (vector-ref p 1) w))) + (let ((l (match-each e (vector-ref p 1) w mod))) (and l (let collect ((l l)) (if (null? (car l)) r (cons (map car l) (collect (map cdr l))))))))) - ((free-id) (and (id? e) (free-id=? (wrap e w) (vector-ref p 1)) r)) + ((free-id) (and (id? e) (free-id=? (wrap e w mod) (vector-ref p 1)) r)) ((atom) (and (equal? (vector-ref p 1) (strip e w)) r)) ((vector) (and (vector? e) - (match (vector->list e) (vector-ref p 1) w r)))))))) + (match (vector->list e) (vector-ref p 1) w r mod)))))))) (define match - (lambda (e p w r) + (lambda (e p w r mod) (cond ((not r) #f) - ((eq? p 'any) (cons (wrap e w) r)) + ((eq? p 'any) (cons (wrap e w mod) r)) ((syntax-object? e) (match* - (unannotate (syntax-object-expression e)) - p - (join-wraps w (syntax-object-wrap e)) - r)) - (else (match* (unannotate e) p w r))))) + (syntax-object-expression e) + p + (join-wraps w (syntax-object-wrap e)) + r + (syntax-object-module e))) + (else (match* e p w r mod))))) -(set! syntax-dispatch +(set! $sc-dispatch (lambda (e p) (cond ((eq? p 'any) (list e)) ((syntax-object? e) - (match* (unannotate (syntax-object-expression e)) - p (syntax-object-wrap e) '())) - (else (match* (unannotate e) p empty-wrap '()))))) + (match* (syntax-object-expression e) + p (syntax-object-wrap e) '() (syntax-object-module e))) + (else (match* e p empty-wrap '() #f))))) -(set! sc-chi chi) )) ) @@ -2066,7 +2288,7 @@ (lambda (x) (syntax-case x () ((let* ((x v) ...) e1 e2 ...) - (andmap identifier? (syntax (x ...))) + (and-map identifier? (syntax (x ...))) (let f ((bindings (syntax ((x v) ...)))) (if (null? bindings) (syntax (let () e1 e2 ...)) @@ -2083,7 +2305,9 @@ (syntax-case s () (() v) ((e) (syntax e)) - (_ (syntax-error orig-x)))) + (_ (syntax-violation + 'do "bad step expression" + orig-x s)))) (syntax (var ...)) (syntax (step ...))))) (syntax-case (syntax (e1 ...)) () @@ -2131,12 +2355,22 @@ (syntax p) (quasicons (syntax (quote unquote)) (quasi (syntax (p)) (- lev 1))))) + ((unquote . args) + (= lev 0) + (syntax-violation 'unquote + "unquote takes exactly one argument" + p (syntax (unquote . args)))) (((unquote-splicing p) . q) (if (= lev 0) (quasiappend (syntax p) (quasi (syntax q) lev)) (quasicons (quasicons (syntax (quote unquote-splicing)) (quasi (syntax (p)) (- lev 1))) (quasi (syntax q) lev)))) + (((unquote-splicing . args) . q) + (= lev 0) + (syntax-violation 'unquote-splicing + "unquote-splicing takes exactly one argument" + p (syntax (unquote-splicing . args)))) ((quasiquote p) (quasicons (syntax (quote quasiquote)) (quasi (syntax (p)) (+ lev 1)))) @@ -2156,29 +2390,29 @@ (let f ((x (read p))) (if (eof-object? x) (begin (close-input-port p) '()) - (cons (datum->syntax-object k x) + (cons (datum->syntax k x) (f (read p)))))))) (syntax-case x () ((k filename) - (let ((fn (syntax-object->datum (syntax filename)))) + (let ((fn (syntax->datum (syntax filename)))) (with-syntax (((exp ...) (read-file fn (syntax k)))) (syntax (begin exp ...)))))))) (define-syntax unquote - (lambda (x) - (syntax-case x () - ((_ e) - (error 'unquote - "expression ,~s not valid outside of quasiquote" - (syntax-object->datum (syntax e))))))) + (lambda (x) + (syntax-case x () + ((_ e) + (syntax-violation 'unquote + "expression not valid outside of quasiquote" + x))))) (define-syntax unquote-splicing - (lambda (x) - (syntax-case x () - ((_ e) - (error 'unquote-splicing - "expression ,@~s not valid outside of quasiquote" - (syntax-object->datum (syntax e))))))) + (lambda (x) + (syntax-case x () + ((_ e) + (syntax-violation 'unquote-splicing + "expression not valid outside of quasiquote" + x))))) (define-syntax case (lambda (x) @@ -2191,14 +2425,15 @@ ((else e1 e2 ...) (syntax (begin e1 e2 ...))) (((k ...) e1 e2 ...) (syntax (if (memv t '(k ...)) (begin e1 e2 ...)))) - (_ (syntax-error x))) + (_ (syntax-violation 'case "bad clause" x clause))) (with-syntax ((rest (f (car clauses) (cdr clauses)))) (syntax-case clause (else) (((k ...) e1 e2 ...) (syntax (if (memv t '(k ...)) (begin e1 e2 ...) rest))) - (_ (syntax-error x)))))))) + (_ (syntax-violation 'case "bad clause" x + clause)))))))) (syntax (let ((t e)) body))))))) (define-syntax identifier-syntax @@ -2213,4 +2448,3 @@ (syntax e)) ((_ x (... ...)) (syntax (e x (... ...))))))))))) - diff --git a/module/ice-9/q.scm b/module/ice-9/q.scm index 0c12d7f40..4dc5d4953 100644 --- a/module/ice-9/q.scm +++ b/module/ice-9/q.scm @@ -5,7 +5,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/module/ice-9/r4rs.scm b/module/ice-9/r4rs.scm index de2aeb2de..c23f31af1 100644 --- a/module/ice-9/r4rs.scm +++ b/module/ice-9/r4rs.scm @@ -6,7 +6,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -17,6 +17,9 @@ ;;;; License along with this library; if not, write to the Free Software ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +(eval-when (compile) + (set-current-module (resolve-module '(guile)))) + ;;;; apply and call-with-current-continuation @@ -186,28 +189,3 @@ procedures, their behavior is implementation dependent." (lambda (p) (with-error-to-port p thunk)))) (define the-eof-object (call-with-input-string "" (lambda (p) (read-char p)))) - - -;;;; Loading - -(if (not (defined? '%load-verbosely)) - (define %load-verbosely #f)) -(define (assert-load-verbosity v) (set! %load-verbosely v)) - -(define (%load-announce file) - (if %load-verbosely - (with-output-to-port (current-error-port) - (lambda () - (display ";;; ") - (display "loading ") - (display file) - (newline) - (force-output))))) - -(set! %load-hook %load-announce) - -(define (load name . reader) - (with-fluid* current-reader (and (pair? reader) (car reader)) - (lambda () - (start-stack 'load-stack - (primitive-load name))))) diff --git a/module/ice-9/r5rs.scm b/module/ice-9/r5rs.scm index 2b40515d3..c867f9a3c 100644 --- a/module/ice-9/r5rs.scm +++ b/module/ice-9/r5rs.scm @@ -3,7 +3,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/module/ice-9/rdelim.scm b/module/ice-9/rdelim.scm index d21d45c38..71aae3c8b 100644 --- a/module/ice-9/rdelim.scm +++ b/module/ice-9/rdelim.scm @@ -5,7 +5,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/module/ice-9/receive.scm b/module/ice-9/receive.scm index 693dfe3f4..d550c6f36 100644 --- a/module/ice-9/receive.scm +++ b/module/ice-9/receive.scm @@ -2,19 +2,19 @@ ;;; Copyright (C) 2000, 2001, 2004, 2006 Free Software Foundation, Inc. ;;; -;; This library is free software; you can redistribute it and/or -;; modify it under the terms of the GNU Lesser General Public -;; License as published by the Free Software Foundation; either -;; version 2.1 of the License, or (at your option) any later version. -;; -;; This library is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;; Lesser General Public License for more details. -;; -;; You should have received a copy of the GNU Lesser General Public -;; License along with this library; if not, write to the Free Software -;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (define-module (ice-9 receive) :export (receive) diff --git a/module/ice-9/regex.scm b/module/ice-9/regex.scm index 61937d04f..2327bfe17 100644 --- a/module/ice-9/regex.scm +++ b/module/ice-9/regex.scm @@ -3,7 +3,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/module/ice-9/runq.scm b/module/ice-9/runq.scm index eb1e2203f..c14eb8967 100644 --- a/module/ice-9/runq.scm +++ b/module/ice-9/runq.scm @@ -5,7 +5,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/module/ice-9/rw.scm b/module/ice-9/rw.scm index 2731e889a..b76282a47 100644 --- a/module/ice-9/rw.scm +++ b/module/ice-9/rw.scm @@ -5,7 +5,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/module/ice-9/safe-r5rs.scm b/module/ice-9/safe-r5rs.scm index 13a44d23d..f728533cb 100644 --- a/module/ice-9/safe-r5rs.scm +++ b/module/ice-9/safe-r5rs.scm @@ -3,7 +3,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/module/ice-9/safe.scm b/module/ice-9/safe.scm index 15b77990a..1ce8f9ed9 100644 --- a/module/ice-9/safe.scm +++ b/module/ice-9/safe.scm @@ -3,7 +3,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/module/ice-9/serialize.scm b/module/ice-9/serialize.scm index 3c70f4421..008a70a9e 100644 --- a/module/ice-9/serialize.scm +++ b/module/ice-9/serialize.scm @@ -3,7 +3,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/module/ice-9/session.scm b/module/ice-9/session.scm index aaa4f0761..1f3ec2795 100644 --- a/module/ice-9/session.scm +++ b/module/ice-9/session.scm @@ -3,7 +3,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/module/ice-9/slib.scm b/module/ice-9/slib.scm index a2b526562..78c734e2a 100644 --- a/module/ice-9/slib.scm +++ b/module/ice-9/slib.scm @@ -5,13 +5,13 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. -;;;; +;;;; version 3 of the License, or (at your option) any later version. +;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;;;; Lesser General Public License for more details. -;;;; +;;;; ;;;; You should have received a copy of the GNU Lesser General Public ;;;; License along with this library; if not, write to the Free Software ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA diff --git a/module/ice-9/stack-catch.scm b/module/ice-9/stack-catch.scm index 2f4b3d145..f7b207535 100644 --- a/module/ice-9/stack-catch.scm +++ b/module/ice-9/stack-catch.scm @@ -5,7 +5,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -40,4 +40,4 @@ this call to @code{catch}." (catch key thunk handler - pre-unwind-handler-dispatch)) + default-pre-unwind-handler)) diff --git a/module/ice-9/streams.scm b/module/ice-9/streams.scm index 317d47245..e0a17d488 100644 --- a/module/ice-9/streams.scm +++ b/module/ice-9/streams.scm @@ -6,7 +6,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/module/ice-9/string-fun.scm b/module/ice-9/string-fun.scm index d8ba21f75..c27ff847f 100644 --- a/module/ice-9/string-fun.scm +++ b/module/ice-9/string-fun.scm @@ -5,7 +5,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/module/ice-9/syncase.scm b/module/ice-9/syncase.scm index 5a5e1a6ea..210a23280 100644 --- a/module/ice-9/syncase.scm +++ b/module/ice-9/syncase.scm @@ -3,7 +3,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -17,236 +17,15 @@ (define-module (ice-9 syncase) - :use-module (ice-9 debug) - :use-module (ice-9 threads) - :export-syntax (sc-macro define-syntax define-syntax-public - eval-when fluid-let-syntax - identifier-syntax let-syntax - letrec-syntax syntax syntax-case syntax-rules - with-syntax - include) - :export (sc-expand sc-expand3 install-global-transformer - syntax-dispatch syntax-error bound-identifier=? - datum->syntax-object free-identifier=? - generate-temporaries identifier? syntax-object->datum - void syncase) - :replace (eval)) + ) - - -(define expansion-eval-closure (make-fluid)) -(define (current-eval-closure) - (or (fluid-ref expansion-eval-closure) - (module-eval-closure (current-module)))) - -(define (env->eval-closure env) - (and env (car (last-pair env)))) - -(define (annotation? x) #f) - -(define sc-macro - (procedure->memoizing-macro - (lambda (exp env) - (with-fluids ((expansion-eval-closure (env->eval-closure env))) - (sc-expand exp))))) - -;;; Exported variables - -(define sc-expand #f) -(define sc-expand3 #f) -(define sc-chi #f) -(define install-global-transformer #f) -(define syntax-dispatch #f) -(define syntax-error #f) - -(define bound-identifier=? #f) -(define datum->syntax-object #f) -(define free-identifier=? #f) -(define generate-temporaries #f) -(define identifier? #f) -(define syntax-object->datum #f) - -(define primitive-syntax '(quote lambda letrec if set! begin define or - and let let* cond do quasiquote unquote - unquote-splicing case)) - -(for-each (lambda (symbol) - (set-symbol-property! symbol 'primitive-syntax #t)) - primitive-syntax) - -;;; Hooks needed by the syntax-case macro package - -(define (void) *unspecified*) - -(define andmap - (lambda (f first . rest) - (or (null? first) - (if (null? rest) - (let andmap ((first first)) - (let ((x (car first)) (first (cdr first))) - (if (null? first) - (f x) - (and (f x) (andmap first))))) - (let andmap ((first first) (rest rest)) - (let ((x (car first)) - (xr (map car rest)) - (first (cdr first)) - (rest (map cdr rest))) - (if (null? first) - (apply f (cons x xr)) - (and (apply f (cons x xr)) (andmap first rest))))))))) - -(define (error who format-string why what) - (start-stack 'syncase-stack - (scm-error 'misc-error - who - "~A ~S" - (list why what) - '()))) - -(define the-syncase-module (current-module)) -(define the-syncase-eval-closure (module-eval-closure the-syncase-module)) - -(fluid-set! expansion-eval-closure the-syncase-eval-closure) - -(define (putprop symbol key binding) - (let* ((eval-closure (current-eval-closure)) - ;; Why not simply do (eval-closure symbol #t)? - ;; Answer: That would overwrite imported bindings - (v (or (eval-closure symbol #f) ;lookup - (eval-closure symbol #t) ;create it locally - ))) - ;; Don't destroy Guile macros corresponding to - ;; primitive syntax when syncase boots. - (if (not (and (symbol-property symbol 'primitive-syntax) - (eq? eval-closure the-syncase-eval-closure))) - (variable-set! v sc-macro)) - ;; Properties are tied to variable objects - (set-object-property! v key binding))) - -(define (getprop symbol key) - (let* ((v ((current-eval-closure) symbol #f))) - (and v - (or (object-property v key) - (and (variable-bound? v) - (macro? (variable-ref v)) - (macro-transformer (variable-ref v)) ;non-primitive - guile-macro))))) - -(define guile-macro - (cons 'external-macro - (lambda (e r w s) - (let ((e (syntax-object->datum e))) - (if (symbol? e) - ;; pass the expression through - e - (let* ((eval-closure (current-eval-closure)) - (m (variable-ref (eval-closure (car e) #f)))) - (if (eq? (macro-type m) 'syntax) - ;; pass the expression through - e - ;; perform Guile macro transform - (let ((e ((macro-transformer m) - e - (append r (list eval-closure))))) - (if (variable? e) - e - (if (null? r) - (sc-expand e) - (sc-chi e r w))))))))))) - -(define generated-symbols (make-weak-key-hash-table 1019)) - -;; We define our own gensym here because the Guile built-in one will -;; eventually produce uninterned and unreadable symbols (as needed for -;; safe macro expansions) and will the be inappropriate for dumping to -;; pssyntax.pp. -;; -;; syncase is supposed to only require that gensym produce unique -;; readable symbols, and they only need be unique with respect to -;; multiple calls to gensym, not globally unique. -;; -(define gensym - (let ((counter 0)) - - (define next-id - (if (provided? 'threads) - (let ((symlock (make-mutex))) - (lambda () - (let ((result #f)) - (with-mutex symlock - (set! result counter) - (set! counter (+ counter 1))) - result))) - ;; faster, non-threaded case. - (lambda () - (let ((result counter)) - (set! counter (+ counter 1)) - result)))) - - ;; actual gensym body code. - (lambda (. rest) - (let* ((next-val (next-id)) - (valstr (number->string next-val))) - (cond - ((null? rest) - (string->symbol (string-append "syntmp-" valstr))) - ((null? (cdr rest)) - (string->symbol (string-append "syntmp-" (car rest) "-" valstr))) - (else - (error - (string-append - "syncase's gensym expected 0 or 1 arguments, got " - (length rest))))))))) - -;;; Load the preprocessed code - -(let ((old-debug #f) - (old-read #f)) - (dynamic-wind (lambda () - (set! old-debug (debug-options)) - (set! old-read (read-options))) - (lambda () - (debug-disable 'debug 'procnames) - (read-disable 'positions) - (load-from-path "ice-9/psyntax-pp")) - (lambda () - (debug-options old-debug) - (read-options old-read)))) - - -;;; The following lines are necessary only if we start making changes -;; (use-syntax sc-expand) -;; (load-from-path "ice-9/psyntax") - -(define internal-eval (nested-ref the-scm-module '(%app modules guile eval))) - -(define (eval x environment) - (internal-eval (if (and (pair? x) - (equal? (car x) "noexpand")) - (cadr x) - (sc-expand x)) - environment)) +(issue-deprecation-warning + "Syntax-case macros are now a part of Guile core; importing (ice-9 syncase) is no longer necessary.") ;;; Hack to make syncase macros work in the slib module -(let ((m (nested-ref the-root-module '(%app modules ice-9 slib)))) - (if m - (set-object-property! (module-local-variable m 'define) - '*sc-expander* - '(define)))) - -(define (syncase exp) - (with-fluids ((expansion-eval-closure - (module-eval-closure (current-module)))) - (sc-expand exp))) - -(set-module-transformer! the-syncase-module syncase) - -(define-syntax define-syntax-public - (syntax-rules () - ((_ name rules ...) - (begin - ;(eval-case ((load-toplevel) (export-syntax name))) - (define-syntax name rules ...))))) - -(fluid-set! expansion-eval-closure #f) +;; FIXME wingo is this still necessary? +;; (let ((m (nested-ref the-root-module '(%app modules ice-9 slib)))) +;; (if m +;; (set-object-property! (module-local-variable m 'define) +;; '*sc-expander* +;; '(define)))) diff --git a/module/ice-9/test.scm b/module/ice-9/test.scm index bed39b621..f6080e4cf 100644 --- a/module/ice-9/test.scm +++ b/module/ice-9/test.scm @@ -1,18 +1,18 @@ ;; Copyright (C) 1991, 1992, 1993, 1994, 1995, 2006 Free Software Foundation, Inc. ;; -;; This library is free software; you can redistribute it and/or -;; modify it under the terms of the GNU Lesser General Public -;; License as published by the Free Software Foundation; either -;; version 2.1 of the License, or (at your option) any later version. -;; -;; This library is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;; Lesser General Public License for more details. -;; -;; You should have received a copy of the GNU Lesser General Public -;; License along with this library; if not, write to the Free Software -;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;;;; "test.scm" Test correctness of scheme implementations. ;;; Author: Aubrey Jaffer diff --git a/module/ice-9/threads.scm b/module/ice-9/threads.scm index bd0f7b745..292d3c27a 100644 --- a/module/ice-9/threads.scm +++ b/module/ice-9/threads.scm @@ -3,7 +3,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -32,21 +32,71 @@ ;;; Code: (define-module (ice-9 threads) - :export (par-map + :export (begin-thread + parallel + letpar + make-thread + with-mutex + monitor + + par-map par-for-each n-par-map n-par-for-each n-for-each-par-map - %thread-handler) - :export-syntax (begin-thread - parallel - letpar - make-thread - with-mutex - monitor)) + %thread-handler)) +;;; Macros first, so that the procedures expand correctly. + +(define-syntax begin-thread + (syntax-rules () + ((_ e0 e1 ...) + (call-with-new-thread + (lambda () e0 e1 ...) + %thread-handler)))) + +(define-syntax parallel + (lambda (x) + (syntax-case x () + ((_ e0 ...) + (with-syntax (((tmp0 ...) (generate-temporaries (syntax (e0 ...))))) + (syntax + (let ((tmp0 (begin-thread e0)) + ...) + (values (join-thread tmp0) ...)))))))) + +(define-syntax letpar + (syntax-rules () + ((_ ((v e) ...) b0 b1 ...) + (call-with-values + (lambda () (parallel e ...)) + (lambda (v ...) + b0 b1 ...))))) + +(define-syntax make-thread + (syntax-rules () + ((_ proc arg ...) + (call-with-new-thread + (lambda () (proc arg ...)) + %thread-handler)))) + +(define-syntax with-mutex + (syntax-rules () + ((_ m e0 e1 ...) + (let ((x m)) + (dynamic-wind + (lambda () (lock-mutex x)) + (lambda () (begin e0 e1 ...)) + (lambda () (unlock-mutex x))))))) + +(define-syntax monitor + (syntax-rules () + ((_ first rest ...) + (with-mutex (make-mutex) + first rest ...)))) + (define (par-mapper mapper) (lambda (proc . arglists) (mapper join-thread @@ -171,52 +221,4 @@ of applying P-PROC on ARGLISTS." ;;; Set system thread handler (define %thread-handler thread-handler) -; --- MACROS ------------------------------------------------------- - -(define-macro (begin-thread . forms) - (if (null? forms) - '(begin) - `(call-with-new-thread - (lambda () - ,@forms) - %thread-handler))) - -(define-macro (parallel . forms) - (cond ((null? forms) '(values)) - ((null? (cdr forms)) (car forms)) - (else - (let ((vars (map (lambda (f) - (make-symbol "f")) - forms))) - `((lambda ,vars - (values ,@(map (lambda (v) `(join-thread ,v)) vars))) - ,@(map (lambda (form) `(begin-thread ,form)) forms)))))) - -(define-macro (letpar bindings . body) - (cond ((or (null? bindings) (null? (cdr bindings))) - `(let ,bindings ,@body)) - (else - (let ((vars (map car bindings))) - `((lambda ,vars - ((lambda ,vars ,@body) - ,@(map (lambda (v) `(join-thread ,v)) vars))) - ,@(map (lambda (b) `(begin-thread ,(cadr b))) bindings)))))) - -(define-macro (make-thread proc . args) - `(call-with-new-thread - (lambda () - (,proc ,@args)) - %thread-handler)) - -(define-macro (with-mutex m . body) - `(dynamic-wind - (lambda () (lock-mutex ,m)) - (lambda () (begin ,@body)) - (lambda () (unlock-mutex ,m)))) - -(define-macro (monitor first . rest) - `(with-mutex ,(make-mutex) - (begin - ,first ,@rest))) - ;;; threads.scm ends here diff --git a/module/ice-9/time.scm b/module/ice-9/time.scm index a7045969f..0fad8dfca 100644 --- a/module/ice-9/time.scm +++ b/module/ice-9/time.scm @@ -3,7 +3,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -53,6 +53,6 @@ result)) (define-macro (time exp) - `(,time-proc (lambda () ,exp))) + `((@@ (ice-9 time) time-proc) (lambda () ,exp))) ;;; time.scm ends here diff --git a/module/ice-9/weak-vector.scm b/module/ice-9/weak-vector.scm index 92d40d840..09e2e0a8d 100644 --- a/module/ice-9/weak-vector.scm +++ b/module/ice-9/weak-vector.scm @@ -5,7 +5,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/module/language/assembly.scm b/module/language/assembly.scm index 28dde1e1a..683da6cc1 100644 --- a/module/language/assembly.scm +++ b/module/language/assembly.scm @@ -2,57 +2,54 @@ ;; Copyright (C) 2001, 2009 Free Software Foundation, Inc. -;; 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 2, 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 COPYING. If not, write to -;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Code: (define-module (language assembly) + #:use-module (rnrs bytevector) #:use-module (system base pmatch) #:use-module (system vm instruction) #:use-module ((srfi srfi-1) #:select (fold)) #:export (byte-length - addr+ align-program + addr+ align-program align-code align-block assembly-pack assembly-unpack object->assembly assembly->object)) -;; nargs, nrest, nlocs, nexts, len, metalen -(define *program-header-len* (+ 1 1 1 1 4 4)) +;; nargs, nrest, nlocs, len, metalen, padding +(define *program-header-len* (+ 1 1 2 4 4 4)) ;; lengths are encoded in 3 bytes (define *len-len* 3) + (define (byte-length assembly) (pmatch assembly (,label (guard (not (pair? label))) 0) - ((load-unsigned-integer ,str) - (+ 1 *len-len* (string-length str))) - ((load-integer ,str) - (+ 1 *len-len* (string-length str))) ((load-number ,str) (+ 1 *len-len* (string-length str))) ((load-string ,str) (+ 1 *len-len* (string-length str))) + ((load-wide-string ,str) + (+ 1 *len-len* (* 4 (string-length str)))) ((load-symbol ,str) (+ 1 *len-len* (string-length str))) - ((load-keyword ,str) - (+ 1 *len-len* (string-length str))) - ((define ,str) - (+ 1 *len-len* (string-length str))) - ((load-program ,nargs ,nrest ,nlocs ,nexts ,labels ,len ,meta . ,code) + ((load-array ,bv) + (+ 1 *len-len* (bytevector-length bv))) + ((load-program ,nargs ,nrest ,nlocs ,labels ,len ,meta . ,code) (+ 1 *program-header-len* len (if meta (1- (byte-length meta)) 0))) ((,inst . _) (guard (>= (instruction-length inst) 0)) (+ 1 (instruction-length inst))) @@ -61,18 +58,28 @@ (define *program-alignment* 8) +(define *block-alignment* 8) + (define (addr+ addr code) (fold (lambda (x len) (+ (byte-length x) len)) addr code)) +(define (code-alignment addr alignment header-len) + (make-list (modulo (- alignment + (modulo (+ addr header-len) alignment)) + alignment) + '(nop))) + +(define (align-block addr) + (code-alignment addr *block-alignment* 0)) + +(define (align-code code addr alignment header-len) + `(,@(code-alignment addr alignment header-len) + ,code)) + (define (align-program prog addr) - `(,@(make-list (modulo (- *program-alignment* - (modulo (1+ addr) *program-alignment*)) - ;; plus the one for the load-program inst itself - *program-alignment*) - '(nop)) - ,prog)) + (align-code prog addr *program-alignment* 1)) ;;; ;;; Code compress/decompression @@ -104,12 +111,26 @@ ((null? x) `(make-eol)) ((and (integer? x) (exact? x)) (cond ((and (<= -128 x) (< x 128)) - `(make-int8 ,(modulo x 256))) + (assembly-pack `(make-int8 ,(modulo x 256)))) ((and (<= -32768 x) (< x 32768)) (let ((n (if (< x 0) (+ x 65536) x))) `(make-int16 ,(quotient n 256) ,(modulo n 256)))) + ((and (<= 0 x #xffffffffffffffff)) + `(make-uint64 ,@(bytevector->u8-list + (let ((bv (make-bytevector 8))) + (bytevector-u64-set! bv 0 x (endianness big)) + bv)))) + ((and (<= 0 (+ x #x8000000000000000) #x7fffffffffffffff)) + `(make-int64 ,@(bytevector->u8-list + (let ((bv (make-bytevector 8))) + (bytevector-s64-set! bv 0 x (endianness big)) + bv)))) (else #f))) - ((char? x) `(make-char8 ,(char->integer x))) + ((char? x) + (cond ((<= (char->integer x) #xff) + `(make-char8 ,(char->integer x))) + (else + `(make-char32 ,(char->integer x))))) (else #f))) (define (assembly->object code) @@ -122,9 +143,23 @@ ((make-int16 ,n1 ,n2) (let ((n (+ (* n1 256) n2))) (if (< n 32768) n (- n 65536)))) + ((make-uint64 ,n1 ,n2 ,n3 ,n4 ,n5 ,n6 ,n7 ,n8) + (bytevector-u64-ref + (u8-list->bytevector (list n1 n2 n3 n4 n5 n6 n7 n8)) + 0 + (endianness big))) + ((make-int64 ,n1 ,n2 ,n3 ,n4 ,n5 ,n6 ,n7 ,n8) + (bytevector-s64-ref + (u8-list->bytevector (list n1 n2 n3 n4 n5 n6 n7 n8)) + 0 + (endianness big))) ((make-char8 ,n) (integer->char n)) + ((make-char32 ,n1 ,n2 ,n3 ,n4) + (integer->char (+ (* n1 #x1000000) + (* n2 #x10000) + (* n3 #x100) + n4))) ((load-string ,s) s) ((load-symbol ,s) (string->symbol s)) - ((load-keyword ,s) (symbol->keyword (string->symbol s))) (else #f))) diff --git a/module/language/assembly/compile-bytecode.scm b/module/language/assembly/compile-bytecode.scm index 6e7e34efc..4706cce64 100644 --- a/module/language/assembly/compile-bytecode.scm +++ b/module/language/assembly/compile-bytecode.scm @@ -2,20 +2,19 @@ ;; Copyright (C) 2001, 2009 Free Software Foundation, Inc. -;; 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 2, 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 COPYING. If not, write to -;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Code: @@ -24,6 +23,7 @@ #:use-module (language assembly) #:use-module (system vm instruction) #:use-module (srfi srfi-4) + #:use-module (rnrs bytevector) #:use-module ((srfi srfi-1) #:select (fold)) #:use-module ((system vm objcode) #:select (byte-order)) #:export (compile-bytecode write-bytecode)) @@ -40,7 +40,7 @@ (get-addr (lambda () i))) (write-bytecode assembly write-byte get-addr '()) (if (= i (u8vector-length v)) - (values v env) + (values v env env) (error "incorrect length in assembly" i (u8vector-length v))))) (else (error "bad assembly" assembly)))) @@ -65,6 +65,14 @@ (write-byte (logand (ash x -8) 255)) (write-byte (logand (ash x -16) 255)) (write-byte (logand (ash x -24) 255))) + (define (write-uint32 x) + (case byte-order + ((1234) (write-uint32-le x)) + ((4321) (write-uint32-be x)) + (else (error "unknown endianness" byte-order)))) + (define (write-wide-string s) + (write-loader-len (* 4 (string-length s))) + (string-for-each (lambda (c) (write-uint32 (char->integer c))) s)) (define (write-loader-len len) (write-byte (ash len -16)) (write-byte (logand (ash len -8) 255)) @@ -72,27 +80,43 @@ (define (write-loader str) (write-loader-len (string-length str)) (write-string str)) + (define (write-sized-loader str) + (let ((len (string-length str)) + (wid (string-width str))) + (write-loader-len len) + (write-byte wid) + (if (= wid 4) + (write-wide-string str) + (write-string str)))) + (define (write-bytevector bv) + (write-loader-len (bytevector-length bv)) + ;; Ew! + (for-each write-byte (bytevector->u8-list bv))) (define (write-break label) - (write-uint16-be (- (assq-ref labels label) (+ (get-addr) 2)))) + (let ((offset (- (assq-ref labels label) + (logand (+ (get-addr) 2) (lognot #x7))))) + (cond ((not (= 0 (modulo offset 8))) (error "unaligned jump" offset)) + ((>= offset (ash 1 18)) (error "jump too far forward" offset)) + ((< offset (- (ash 1 18))) (error "jump too far backwards" offset)) + (else (write-uint16-be (ash offset -3)))))) (let ((inst (car asm)) (args (cdr asm)) - (write-uint32 (case byte-order - ((1234) write-uint32-le) - ((4321) write-uint32-be) + (write-uint16 (case byte-order + ((1234) write-uint16-le) + ((4321) write-uint16-be) (else (error "unknown endianness" byte-order))))) (let ((opcode (instruction->opcode inst)) (len (instruction-length inst))) (write-byte opcode) (pmatch asm - ((load-program ,nargs ,nrest ,nlocs ,nexts - ,labels ,length ,meta . ,code) + ((load-program ,nargs ,nrest ,nlocs ,labels ,length ,meta . ,code) (write-byte nargs) (write-byte nrest) - (write-byte nlocs) - (write-byte nexts) + (write-uint16 nlocs) (write-uint32 length) (write-uint32 (if meta (1- (byte-length meta)) 0)) + (write-uint32 0) ; padding (letrec ((i 0) (write (lambda (x) (set! i (1+ i)) (write-byte x))) (get-addr (lambda () i))) @@ -106,14 +130,16 @@ (set! i (1+ i)) (if (> i 0) (write-byte x)))) (get-addr (lambda () i))) + ;; META's bytecode meets the alignment requirements of + ;; `scm_objcode', thanks to the alignment computed in + ;; `(language assembly)'. (write-bytecode meta write get-addr '())))) - ((load-unsigned-integer ,str) (write-loader str)) - ((load-integer ,str) (write-loader str)) + ((make-char32 ,x) (write-uint32-be x)) ((load-number ,str) (write-loader str)) ((load-string ,str) (write-loader str)) + ((load-wide-string ,str) (write-wide-string str)) ((load-symbol ,str) (write-loader str)) - ((load-keyword ,str) (write-loader str)) - ((define ,str) (write-loader str)) + ((load-array ,bv) (write-bytevector bv)) ((br ,l) (write-break l)) ((br-if ,l) (write-break l)) ((br-if-not ,l) (write-break l)) diff --git a/module/language/assembly/decompile-bytecode.scm b/module/language/assembly/decompile-bytecode.scm index e65b2cbaa..8cdebcfd0 100644 --- a/module/language/assembly/decompile-bytecode.scm +++ b/module/language/assembly/decompile-bytecode.scm @@ -1,21 +1,20 @@ ;;; Guile VM code converters -;; Copyright (C) 2001 Free Software Foundation, Inc. +;; Copyright (C) 2001, 2009 Free Software Foundation, Inc. -;; 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 2, 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 COPYING. If not, write to -;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Code: @@ -23,7 +22,9 @@ #:use-module (system vm instruction) #:use-module (system base pmatch) #:use-module (srfi srfi-4) + #:use-module (rnrs bytevector) #:use-module (language assembly) + #:use-module ((system vm objcode) #:select (byte-order)) #:export (decompile-bytecode)) (define (decompile-bytecode x env opts) @@ -48,17 +49,21 @@ x (- x (ash 1 16))))) +;; FIXME: this is a little-endian disassembly!!! (define (decode-load-program pop) - (let* ((nargs (pop)) (nrest (pop)) (nlocs (pop)) (nexts (pop)) + (let* ((nargs (pop)) (nrest (pop)) (nlocs0 (pop)) (nlocs1 (pop)) + (nlocs (+ nlocs0 (ash nlocs1 8))) (a (pop)) (b (pop)) (c (pop)) (d (pop)) (e (pop)) (f (pop)) (g (pop)) (h (pop)) (len (+ a (ash b 8) (ash c 16) (ash d 24))) (metalen (+ e (ash f 8) (ash g 16) (ash h 24))) (totlen (+ len metalen)) + (pad0 (pop)) (pad1 (pop)) (pad2 (pop)) (pad3 (pop)) (labels '()) (i 0)) (define (ensure-label rel1 rel2) - (let ((where (+ i (bytes->s16 rel1 rel2)))) + (let ((where (+ (logand i (lognot #x7)) + (* (bytes->s16 rel1 rel2) 8)))) (or (assv-ref labels where) (begin (let ((l (gensym ":L"))) @@ -74,7 +79,7 @@ (cond ((> i len) (error "error decoding program -- read too many bytes" out)) ((= i len) - `(load-program ,nargs ,nrest ,nlocs ,nexts + `(load-program ,nargs ,nrest ,nlocs ,(map (lambda (x) (cons (cdr x) (car x))) (reverse labels)) ,len @@ -97,15 +102,29 @@ (cond ((eq? inst 'load-program) (decode-load-program pop)) + ((< (instruction-length inst) 0) - (let* ((len (let* ((a (pop)) (b (pop)) (c (pop))) + ;; the negative length indicates a variable length + ;; instruction + (let* ((make-sequence + (if (or (memq inst '(load-array load-wide-string))) + make-bytevector + make-string)) + (sequence-set! + (if (or (memq inst '(load-array load-wide-string))) + bytevector-u8-set! + (lambda (str pos value) + (string-set! str pos (integer->char value))))) + (len (let* ((a (pop)) (b (pop)) (c (pop))) (+ (ash a 16) (ash b 8) c))) - (str (make-string len))) + (seq (make-sequence len))) (let lp ((i 0)) (if (= i len) - `(,inst ,str) + `(,inst ,(if (eq? inst 'load-wide-string) + (utf32->string seq) + seq)) (begin - (string-set! str i (integer->char (pop))) + (sequence-set! seq i (pop)) (lp (1+ i))))))) (else ;; fixed length diff --git a/module/language/assembly/disassemble.scm b/module/language/assembly/disassemble.scm index 2752934f9..492acb7e5 100644 --- a/module/language/assembly/disassemble.scm +++ b/module/language/assembly/disassemble.scm @@ -1,21 +1,20 @@ ;;; Guile VM code converters -;; Copyright (C) 2001 Free Software Foundation, Inc. +;; Copyright (C) 2001, 2009 Free Software Foundation, Inc. -;; 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 2, 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 COPYING. If not, write to -;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Code: @@ -36,12 +35,11 @@ (define (disassemble-load-program asm env) (pmatch asm - ((load-program ,nargs ,nrest ,nlocs ,nexts ,labels ,len ,meta . ,code) + ((load-program ,nargs ,nrest ,nlocs ,labels ,len ,meta . ,code) (let ((objs (and env (assq-ref env 'objects))) + (free-vars (and env (assq-ref env 'free-vars))) (meta (and env (assq-ref env 'meta))) - (exts (and env (assq-ref env 'exts))) (blocs (and env (assq-ref env 'blocs))) - (bexts (and env (assq-ref env 'bexts))) (srcs (and env (assq-ref env 'sources)))) (let lp ((pos 0) (code code) (programs '())) (cond @@ -62,15 +60,17 @@ (print-info pos `(load-program ,sym) #f #f) (lp (+ pos (byte-length asm)) (cdr code) (acons sym asm programs)))) + ((nop) + (lp (+ pos (byte-length asm)) (cdr code) programs)) (else (print-info pos asm - (code-annotation end asm objs nargs blocs bexts + (code-annotation end asm objs nargs blocs labels) (and=> (and srcs (assq end srcs)) source->string)) (lp (+ pos (byte-length asm)) (cdr code) programs))))))) - (if (pair? exts) - (disassemble-externals exts)) + (if (pair? free-vars) + (disassemble-free-vars free-vars)) (if meta (disassemble-meta meta)) @@ -82,7 +82,7 @@ (if (program? x) (begin (display "----------------------------------------\n") (disassemble x)))) - (cddr (vector->list objs)))))) + (cdr (vector->list objs)))))) (else (error "bad load-program form" asm)))) @@ -93,13 +93,12 @@ ((= n len) (newline)) (print-info n (vector-ref objs n) #f #f)))) -(define (disassemble-externals exts) - (display "Externals:\n\n") - (let ((len (length exts))) - (do ((n 0 (1+ n)) - (l exts (cdr l))) - ((null? l) (newline)) - (print-info n (car l) #f #f)))) +(define (disassemble-free-vars free-vars) + (display "Free variables:\n\n") + (let ((i 0)) + (cond ((< i (vector-length free-vars)) + (print-info i (vector-ref free-vars i) #f #f) + (lp (1+ i)))))) (define-macro (unless test . body) `(if (not ,test) (begin ,@body))) @@ -123,7 +122,7 @@ (define (make-int16 byte1 byte2) (+ (* byte1 256) byte2)) -(define (code-annotation end-addr code objs nargs blocs bexts labels) +(define (code-annotation end-addr code objs nargs blocs labels) (let* ((code (assembly-unpack code)) (inst (car code)) (args (cdr code))) @@ -134,7 +133,7 @@ (list "-> ~A" (assq-ref labels (car args)))) ((object-ref) (and objs (list "~s" (vector-ref objs (car args))))) - ((local-ref local-set) + ((local-ref local-boxed-ref local-set local-boxed-set) (and blocs (let lp ((bindings (list-ref blocs (car args)))) (and (pair? bindings) @@ -144,13 +143,9 @@ (list "`~a'~@[ (arg)~]" (binding:name b) (< (binding:index b) nargs)) (lp (cdr bindings)))))))) - ((external-ref external-set) - (and bexts - (if (< (car args) (length bexts)) - (let ((b (list-ref bexts (car args)))) - (list "`~a'~@[ (arg)~]" - (binding:name b) (< (binding:index b) nargs))) - (list "(closure variable)")))) + ((free-ref free-boxed-ref free-boxed-set) + ;; FIXME: we can do better than this + (list "(closure variable)")) ((toplevel-ref toplevel-set) (and objs (let ((v (vector-ref objs (car args)))) diff --git a/module/language/assembly/spec.scm b/module/language/assembly/spec.scm index c12808e0c..286c80511 100644 --- a/module/language/assembly/spec.scm +++ b/module/language/assembly/spec.scm @@ -2,20 +2,19 @@ ;; Copyright (C) 2001 Free Software Foundation, Inc. -;; 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 2, 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 COPYING. If not, write to -;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Code: diff --git a/module/language/brainfuck/compile-scheme.scm b/module/language/brainfuck/compile-scheme.scm new file mode 100644 index 000000000..86bc35fdd --- /dev/null +++ b/module/language/brainfuck/compile-scheme.scm @@ -0,0 +1,126 @@ +;;; Brainfuck for GNU Guile + +;; Copyright (C) 2009 Free Software Foundation, Inc. + +;; This library is free software; you can redistribute it and/or +;; modify it under the terms of the GNU Lesser General Public +;; License as published by the Free Software Foundation; either +;; version 3 of the License, or (at your option) any later version. +;; +;; This library is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; Lesser General Public License for more details. +;; +;; You should have received a copy of the GNU Lesser General Public +;; License along with this library; if not, write to the Free Software +;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +;;; Code: + +(define-module (language brainfuck compile-scheme) + #:export (compile-scheme)) + +;; Compilation of Brainfuck to Scheme is pretty straight-forward. For all of +;; brainfuck's instructions, there are basic representations in Scheme we +;; only have to generate. +;; +;; Brainfuck's pointer and data-tape are stored in the variables pointer and +;; tape, where tape is a vector of integer values initially set to zero. Pointer +;; starts out at position 0. +;; Our tape is thus of finite length, with an address range of 0..n for +;; some defined upper bound n depending on the length of our tape. + + +;; Define the length to use for the tape. + +(define tape-size 30000) + + +;; This compiles a whole brainfuck program. This constructs a Scheme code like: +;; (let ((pointer 0) +;; (tape (make-vector tape-size 0))) +;; (begin +;; +;; (write-char #\newline))) +;; +;; So first the pointer and tape variables are set up correctly, then the +;; program's body is executed in this context, and finally we output an +;; additional newline character in case the program does not output one. +;; +;; TODO: Find out and explain the details about env, the three return values and +;; how to use the options. Implement options to set the tape-size, maybe. + +(define (compile-scheme exp env opts) + (values + `(let ((pointer 0) + (tape (make-vector ,tape-size 0))) + ,@(if (not (eq? ' (car exp))) + (error "expected brainfuck program") + `(begin + ,@(compile-body (cdr exp)) + (write-char #\newline)))) + env + env)) + + +;; Compile a list of instructions to get a list of Scheme codes. As we always +;; strip off the car of the instructions-list and cons the result onto the +;; result-list, it will get out in reversed order first; so we have to (reverse) +;; it on return. + +(define (compile-body instructions) + (let iterate ((cur instructions) + (result '())) + (if (null? cur) + (reverse result) + (let ((compiled (compile-instruction (car cur)))) + (iterate (cdr cur) (cons compiled result)))))) + + +;; Compile a single instruction to Scheme, using the direct representations +;; all of Brainfuck's instructions have. + +(define (compile-instruction ins) + (case (car ins) + + ;; Pointer moval >< is done simply by something like: + ;; (set! pointer (+ pointer +-1)) + (() + (let ((dir (cadr ins))) + `(set! pointer (+ pointer ,dir)))) + + ;; Cell increment +- is done as: + ;; (vector-set! tape pointer (+ (vector-ref tape pointer) +-1)) + (() + (let ((inc (cadr ins))) + `(vector-set! tape pointer (+ (vector-ref tape pointer) ,inc)))) + + ;; Output . is done by converting the cell's integer value to a character + ;; first and then printing out this character: + ;; (write-char (integer->char (vector-ref tape pointer))) + (() + '(write-char (integer->char (vector-ref tape pointer)))) + + ;; Input , is done similarly, read in a character, get its ASCII code and + ;; store it into the current cell: + ;; (vector-set! tape pointer (char->integer (read-char))) + (() + '(vector-set! tape pointer (char->integer (read-char)))) + + ;; For loops [...] we use a named let construction to execute the body until + ;; the current cell gets zero. The body is compiled via a recursive call + ;; back to (compile-body). + ;; (let iterate () + ;; (if (not (= (vector-ref! tape pointer) 0)) + ;; (begin + ;; + ;; (iterate)))) + (() + `(let iterate () + (if (not (= (vector-ref tape pointer) 0)) + (begin + ,@(compile-body (cdr ins)) + (iterate))))) + + (else (error "unknown brainfuck instruction " (car ins))))) diff --git a/module/language/brainfuck/compile-tree-il.scm b/module/language/brainfuck/compile-tree-il.scm new file mode 100644 index 000000000..0aaa11274 --- /dev/null +++ b/module/language/brainfuck/compile-tree-il.scm @@ -0,0 +1,181 @@ +;;; Brainfuck for GNU Guile + +;; Copyright (C) 2009 Free Software Foundation, Inc. + +;; This library is free software; you can redistribute it and/or +;; modify it under the terms of the GNU Lesser General Public +;; License as published by the Free Software Foundation; either +;; version 3 of the License, or (at your option) any later version. +;; +;; This library is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; Lesser General Public License for more details. +;; +;; You should have received a copy of the GNU Lesser General Public +;; License along with this library; if not, write to the Free Software +;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +;; 02110-1301 USA + +;;; Commentary: + +;; Brainfuck is a simple language that mostly mimics the operations of a +;; Turing machine. This file implements a compiler from Brainfuck to +;; Guile's Tree-IL. + +;;; Code: + +(define-module (language brainfuck compile-tree-il) + #:use-module (system base pmatch) + #:use-module (language tree-il) + #:export (compile-tree-il)) + +;; Compilation of Brainfuck is pretty straight-forward. For all of +;; brainfuck's instructions, there are basic representations in Tree-IL +;; we only have to generate. +;; +;; Brainfuck's pointer and data-tape are stored in the variables pointer and +;; tape, where tape is a vector of integer values initially set to zero. Pointer +;; starts out at position 0. +;; Our tape is thus of finite length, with an address range of 0..n for +;; some defined upper bound n depending on the length of our tape. + + +;; Define the length to use for the tape. + +(define tape-size 30000) + + +;; This compiles a whole brainfuck program. This constructs a Tree-IL +;; code equivalent to Scheme code like this: +;; +;; (let ((pointer 0) +;; (tape (make-vector tape-size 0))) +;; (begin +;; +;; (write-char #\newline))) +;; +;; So first the pointer and tape variables are set up correctly, then the +;; program's body is executed in this context, and finally we output an +;; additional newline character in case the program does not output one. +;; +;; The fact that we are compiling to Guile primitives gives this +;; implementation a number of interesting characteristics. First, the +;; values of the tape cells do not underflow or overflow. We could make +;; them do otherwise via compiling calls to "modulo" at certain points. +;; +;; In addition, tape overruns or underruns will be detected, and will +;; throw an error, whereas a number of Brainfuck compilers do not detect +;; this. +;; +;; Note that we're generating the S-expression representation of +;; Tree-IL, then using parse-tree-il to turn it into the actual Tree-IL +;; data structures. This makes the compiler more pleasant to look at, +;; but we do lose is the ability to propagate source information. Since +;; Brainfuck is so obtuse anyway, this shouldn't matter ;-) +;; +;; `compile-tree-il' takes as its input the read expression, the +;; environment, and some compile options. It returns the compiled +;; expression, the environment appropriate for the next pass of the +;; compiler -- in our case, just the environment unchanged -- and the +;; continuation environment. +;; +;; The normal use of a continuation environment is if compiling one +;; expression changes the environment, and that changed environment +;; should be passed to the next compiled expression -- for example, +;; changing the current module. But Brainfuck is incapable of that, so +;; for us, the continuation environment is just the same environment we +;; got in. +;; +;; FIXME: perhaps use options or the env to set the tape-size? + +(define (compile-tree-il exp env opts) + (values + (parse-tree-il + `(let (pointer tape) (pointer tape) + ((const 0) + (apply (primitive make-vector) (const ,tape-size) (const 0))) + ,(compile-body exp))) + env + env)) + + +;; Compile a list of instructions to a Tree-IL expression. + +(define (compile-body instructions) + (let lp ((in instructions) (out '())) + (define (emit x) + (lp (cdr in) (cons x out))) + (cond + ((null? in) + ;; No more input, build our output. + (cond + ((null? out) '(void)) ; no output + ((null? (cdr out)) (car out)) ; single expression + (else `(begin ,@(reverse out)))) ; sequence + ) + (else + (pmatch (car in) + + ;; Pointer moves >< are done simply by something like: + ;; (set! pointer (+ pointer +-1)) + (( ,dir) + (emit `(set! (lexical pointer) + (apply (primitive +) (lexical pointer) (const ,dir))))) + + ;; Cell increment +- is done as: + ;; (vector-set! tape pointer (+ (vector-ref tape pointer) +-1)) + (( ,inc) + (emit `(apply (primitive vector-set!) (lexical tape) (lexical pointer) + (apply (primitive +) + (apply (primitive vector-ref) + (lexical tape) (lexical pointer)) + (const ,inc))))) + + ;; Output . is done by converting the cell's integer value to a + ;; character first and then printing out this character: + ;; (write-char (integer->char (vector-ref tape pointer))) + (() + (emit `(apply (primitive write-char) + (apply (primitive integer->char) + (apply (primitive vector-ref) + (lexical tape) (lexical pointer)))))) + + ;; Input , is done similarly, read in a character, get its ASCII + ;; code and store it into the current cell: + ;; (vector-set! tape pointer (char->integer (read-char))) + (() + (emit `(apply (primitive vector-set!) + (lexical tape) (lexical pointer) + (apply (primitive char->integer) + (apply (primitive read-char)))))) + + ;; For loops [...] we use a letrec construction to execute the body until + ;; the current cell gets zero. The body is compiled via a recursive call + ;; back to (compile-body). + ;; (let iterate () + ;; (if (not (= (vector-ref! tape pointer) 0)) + ;; (begin + ;; + ;; (iterate)))) + ;; + ;; Indeed, letrec is the only way we have to loop in Tree-IL. + ;; Note that this does not mean that the closure must actually + ;; be created; later passes can compile tail-recursive letrec + ;; calls into inline code with gotos. Admittedly, that part of + ;; the compiler is not yet in place, but it will be, and in the + ;; meantime the code is still reasonably efficient. + (( . ,body) + (let ((iterate (gensym))) + (emit `(letrec (iterate) (,iterate) + ((lambda () () + (if (apply (primitive =) + (apply (primitive vector-ref) + (lexical tape) (lexical pointer)) + (const 0)) + (void) + (begin ,(compile-body body) + (apply (lexical ,iterate)))))) + (apply (lexical ,iterate)))))) + + (else (error "unknown brainfuck instruction" (car in)))))))) diff --git a/module/language/brainfuck/parse.scm b/module/language/brainfuck/parse.scm new file mode 100644 index 000000000..0a71638d8 --- /dev/null +++ b/module/language/brainfuck/parse.scm @@ -0,0 +1,91 @@ +;;; Brainfuck for GNU Guile. + +;; Copyright (C) 2009 Free Software Foundation, Inc. + +;; This library is free software; you can redistribute it and/or +;; modify it under the terms of the GNU Lesser General Public +;; License as published by the Free Software Foundation; either +;; version 3 of the License, or (at your option) any later version. +;; +;; This library is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; Lesser General Public License for more details. +;; +;; You should have received a copy of the GNU Lesser General Public +;; License along with this library; if not, write to the Free Software +;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +;; 02110-1301 USA + +;;; Code: + +(define-module (language brainfuck parse) + #:export (read-brainfuck)) + +; Purpose of the parse module is to read in brainfuck in text form and produce +; the corresponding tree representing the brainfuck code. +; +; Each object (representing basically a single instruction) is structured like: +; ( [arguments]) +; where is a symbolic name representing the type of instruction +; and the optional arguments represent further data (for instance, the body of +; a [...] loop as a number of nested instructions). +; +; A full brainfuck program is represented by the ( instructions) +; object. + + +; While reading a number of instructions in sequence, all of them are cons'ed +; onto a list of instructions; thus this list gets out in reverse order. +; Additionally, for "comment characters" (everything not an instruction) we +; generate NOP instructions. +; +; This routine reverses a list of instructions and removes all 's on the +; way to fix these two issues for a read-in list. + +(define (reverse-without-nops lst) + (let iterate ((cur lst) + (result '())) + (if (null? cur) + result + (let ((head (car cur)) + (tail (cdr cur))) + (if (eq? (car head) ') + (iterate tail result) + (iterate tail (cons head result))))))) + + +; Read in a set of instructions until a terminating ] character is found (or +; end of file is reached). This is used both for loop bodies and whole +; programs, so that a program has to be either terminated by EOF or an +; additional ], too. +; +; For instance, the basic program so just echo one character would be: +; ,.] + +(define (read-brainfuck p) + (let iterate ((parsed '())) + (let ((chr (read-char p))) + (if (or (eof-object? chr) (eq? #\] chr)) + (reverse-without-nops parsed) + (iterate (cons (process-input-char chr p) parsed)))))) + + +; This routine processes a single character of input and builds the +; corresponding instruction. Loop bodies are read by recursively calling +; back (read-brainfuck). +; +; For the poiner movement commands >< and the cell increment/decrement +- +; commands, we only use one instruction form each and specify the direction of +; the pointer/value increment using an argument to the instruction form. + +(define (process-input-char chr p) + (case chr + ((#\>) '( 1)) + ((#\<) '( -1)) + ((#\+) '( 1)) + ((#\-) '( -1)) + ((#\.) '()) + ((#\,) '()) + ((#\[) `( ,@(read-brainfuck p))) + (else '()))) diff --git a/module/language/brainfuck/spec.scm b/module/language/brainfuck/spec.scm new file mode 100644 index 000000000..a4ba60f82 --- /dev/null +++ b/module/language/brainfuck/spec.scm @@ -0,0 +1,44 @@ +;;; Brainfuck for GNU Guile. + +;; Copyright (C) 2009 Free Software Foundation, Inc. + +;; This library is free software; you can redistribute it and/or +;; modify it under the terms of the GNU Lesser General Public +;; License as published by the Free Software Foundation; either +;; version 3 of the License, or (at your option) any later version. +;; +;; This library is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; Lesser General Public License for more details. +;; +;; You should have received a copy of the GNU Lesser General Public +;; License along with this library; if not, write to the Free Software +;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +;; 02110-1301 USA + +;;; Code: + +(define-module (language brainfuck spec) + #:use-module (language brainfuck compile-tree-il) + #:use-module (language brainfuck compile-scheme) + #:use-module (language brainfuck parse) + #:use-module (system base language) + #:export (brainfuck)) + + +; The new language is integrated into Guile via this (define-language) +; specification in the special module (language [lang] spec). +; Provided is a parser-routine in #:reader, a output routine in #:printer +; and one or more compiler routines (as target-language - routine pairs) +; in #:compilers. This is the basic set of fields needed to specify a new +; language. + +(define-language brainfuck + #:title "Guile Brainfuck" + #:version "1.0" + #:reader (lambda () (read-brainfuck (current-input-port))) + #:compilers `((tree-il . ,compile-tree-il) + (scheme . ,compile-scheme)) + #:printer write + ) diff --git a/module/language/bytecode/spec.scm b/module/language/bytecode/spec.scm index 7d9b955a7..184565b04 100644 --- a/module/language/bytecode/spec.scm +++ b/module/language/bytecode/spec.scm @@ -2,20 +2,19 @@ ;; Copyright (C) 2001 Free Software Foundation, Inc. -;; 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 2, 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 COPYING. If not, write to -;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Code: @@ -25,7 +24,7 @@ #:export (bytecode)) (define (compile-objcode x e opts) - (values (bytecode->objcode x) e)) + (values (bytecode->objcode x) e e)) (define (decompile-objcode x e opts) (values (objcode->bytecode x) e)) diff --git a/module/language/ecmascript/array.scm b/module/language/ecmascript/array.scm index a9f499a22..e9fc3c6f4 100644 --- a/module/language/ecmascript/array.scm +++ b/module/language/ecmascript/array.scm @@ -2,20 +2,19 @@ ;; Copyright (C) 2009 Free Software Foundation, Inc. -;; 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 2, 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 COPYING. If not, write to -;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Code: diff --git a/module/language/ecmascript/base.scm b/module/language/ecmascript/base.scm index 1463d358b..1d031fcde 100644 --- a/module/language/ecmascript/base.scm +++ b/module/language/ecmascript/base.scm @@ -2,20 +2,19 @@ ;; Copyright (C) 2009 Free Software Foundation, Inc. -;; 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 2, 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 COPYING. If not, write to -;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Code: diff --git a/module/language/ecmascript/compile-ghil.scm b/module/language/ecmascript/compile-ghil.scm deleted file mode 100644 index d4c2261a0..000000000 --- a/module/language/ecmascript/compile-ghil.scm +++ /dev/null @@ -1,572 +0,0 @@ -;;; ECMAScript for Guile - -;; Copyright (C) 2009 Free Software Foundation, Inc. - -;; 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 2, 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 COPYING. If not, write to -;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Code: - -(define-module (language ecmascript compile-ghil) - #:use-module (language ghil) - #:use-module (ice-9 receive) - #:use-module (system base pmatch) - #:export (compile-ghil)) - -(define-macro (-> form) - `(,(symbol-append 'make-ghil- (car form)) e l . ,(cdr form))) - -(define-macro (@implv sym) - `(-> (ref (ghil-var-at-module! e '(language ecmascript impl) ',sym #t)))) -(define-macro (@impl sym args) - `(-> (call (@implv ,sym) ,args))) - -(define (compile-ghil exp env opts) - (values - (call-with-ghil-environment (make-ghil-toplevel-env) '() - (lambda (e vars) - (let ((l #f)) - (-> (lambda vars #f '() - (-> (begin (list (@impl js-init '()) - (comp exp e))))))))) - env)) - -(define (location x) - (and (pair? x) - (let ((props (source-properties x))) - (and (not (null? props)) - props)))) - -;; The purpose, you ask? To avoid non-tail recursion when expanding a -;; long pmatch sequence. -(define-macro (ormatch x . clauses) - (let ((X (gensym))) - `(let ((,X ,x)) - (or ,@(map (lambda (c) - (if (eq? (car c) 'else) - `(begin . ,(cdr c)) - `(pmatch ,X ,c (else #f)))) - clauses))))) - -(define (comp x e) - (let ((l (location x))) - (define (let1 what proc) - (call-with-ghil-bindings e '(%tmp) - (lambda (vars) - (-> (bind vars (list what) - (proc (car vars))))))) - (define (begin1 what proc) - (call-with-ghil-bindings e '(%tmp) - (lambda (vars) - (-> (bind vars (list what) - (-> (begin (list (proc (car vars)) - (-> (ref (car vars))))))))))) - (ormatch x - (null - ;; FIXME, null doesn't have much relation to EOL... - (-> (quote '()))) - (true - (-> (quote #t))) - (false - (-> (quote #f))) - ((number ,num) - (-> (quote num))) - ((string ,str) - (-> (quote str))) - (this - (@impl get-this '())) - ((+ ,a) - (-> (inline 'add - (list (@impl ->number (list (comp a e))) - (-> (quote 0)))))) - ((- ,a) - (-> (inline 'sub (list (-> (quote 0)) (comp a e))))) - ((~ ,a) - (@impl bitwise-not (list (comp a e)))) - ((! ,a) - (@impl logical-not (list (comp a e)))) - ((+ ,a ,b) - (-> (inline 'add (list (comp a e) (comp b e))))) - ((- ,a ,b) - (-> (inline 'sub (list (comp a e) (comp b e))))) - ((/ ,a ,b) - (-> (inline 'div (list (comp a e) (comp b e))))) - ((* ,a ,b) - (-> (inline 'mul (list (comp a e) (comp b e))))) - ((% ,a ,b) - (@impl mod (list (comp a e) (comp b e)))) - ((<< ,a ,b) - (@impl shift (list (comp a e) (comp b e)))) - ((>> ,a ,b) - (@impl shift (list (comp a e) (comp `(- ,b) e)))) - ((< ,a ,b) - (-> (inline 'lt? (list (comp a e) (comp b e))))) - ((<= ,a ,b) - (-> (inline 'le? (list (comp a e) (comp b e))))) - ((> ,a ,b) - (-> (inline 'gt? (list (comp a e) (comp b e))))) - ((>= ,a ,b) - (-> (inline 'ge? (list (comp a e) (comp b e))))) - ((in ,a ,b) - (@impl has-property? (list (comp a e) (comp b e)))) - ((== ,a ,b) - (-> (inline 'equal? (list (comp a e) (comp b e))))) - ((!= ,a ,b) - (-> (inline 'not - (list (-> (inline 'equal? - (list (comp a e) (comp b e)))))))) - ((=== ,a ,b) - (-> (inline 'eqv? (list (comp a e) (comp b e))))) - ((!== ,a ,b) - (-> (inline 'not - (list (-> (inline 'eqv? - (list (comp a e) (comp b e)))))))) - ((& ,a ,b) - (@impl band (list (comp a e) (comp b e)))) - ((^ ,a ,b) - (@impl bxor (list (comp a e) (comp b e)))) - ((bor ,a ,b) - (@impl bior (list (comp a e) (comp b e)))) - ((and ,a ,b) - (-> (and (list (comp a e) (comp b e))))) - ((or ,a ,b) - (-> (or (list (comp a e) (comp b e))))) - ((if ,test ,then ,else) - (-> (if (@impl ->boolean (list (comp test e))) - (comp then e) - (comp else e)))) - ((if ,test ,then ,else) - (-> (if (@impl ->boolean (list (comp test e))) - (comp then e) - (@implv *undefined*)))) - ((postinc (ref ,foo)) - (begin1 (comp `(ref ,foo) e) - (lambda (var) - (-> (set (ghil-var-for-set! e foo) - (-> (inline 'add - (list (-> (ref var)) - (-> (quote 1)))))))))) - ((postinc (pref ,obj ,prop)) - (let1 (comp obj e) - (lambda (objvar) - (begin1 (@impl pget - (list (-> (ref objvar)) - (-> (quote prop)))) - (lambda (tmpvar) - (@impl pput - (list (-> (ref objvar)) - (-> (quote prop)) - (-> (inline 'add - (list (-> (ref tmpvar)) - (-> (quote 1)))))))))))) - ((postinc (aref ,obj ,prop)) - (let1 (comp obj e) - (lambda (objvar) - (let1 (comp prop e) - (lambda (propvar) - (begin1 (@impl pget - (list (-> (ref objvar)) - (-> (ref propvar)))) - (lambda (tmpvar) - (@impl pput - (list (-> (ref objvar)) - (-> (ref propvar)) - (-> (inline 'add - (list (-> (ref tmpvar)) - (-> (quote 1)))))))))))))) - ((postdec (ref ,foo)) - (begin1 (comp `(ref ,foo) e) - (lambda (var) - (-> (set (ghil-var-for-set! e foo) - (-> (inline 'sub - (list (-> (ref var)) - (-> (quote 1)))))))))) - ((postdec (pref ,obj ,prop)) - (let1 (comp obj e) - (lambda (objvar) - (begin1 (@impl pget - (list (-> (ref objvar)) - (-> (quote prop)))) - (lambda (tmpvar) - (@impl pput - (list (-> (ref objvar)) - (-> (quote prop)) - (-> (inline 'sub - (list (-> (ref tmpvar)) - (-> (quote 1)))))))))))) - ((postdec (aref ,obj ,prop)) - (let1 (comp obj e) - (lambda (objvar) - (let1 (comp prop e) - (lambda (propvar) - (begin1 (@impl pget - (list (-> (ref objvar)) - (-> (ref propvar)))) - (lambda (tmpvar) - (@impl pput - (list (-> (ref objvar)) - (-> (ref propvar)) - (-> (inline - 'sub (list (-> (ref tmpvar)) - (-> (quote 1)))))))))))))) - ((preinc (ref ,foo)) - (let ((v (ghil-var-for-set! e foo))) - (-> (begin - (list - (-> (set v - (-> (inline 'add - (list (-> (ref v)) - (-> (quote 1))))))) - (-> (ref v))))))) - ((preinc (pref ,obj ,prop)) - (let1 (comp obj e) - (lambda (objvar) - (begin1 (-> (inline 'add - (list (@impl pget - (list (-> (ref objvar)) - (-> (quote prop)))) - (-> (quote 1))))) - (lambda (tmpvar) - (@impl pput (list (-> (ref objvar)) - (-> (quote prop)) - (-> (ref tmpvar))))))))) - ((preinc (aref ,obj ,prop)) - (let1 (comp obj e) - (lambda (objvar) - (let1 (comp prop e) - (lambda (propvar) - (begin1 (-> (inline 'add - (list (@impl pget - (list (-> (ref objvar)) - (-> (ref propvar)))) - (-> (quote 1))))) - (lambda (tmpvar) - (@impl pput - (list (-> (ref objvar)) - (-> (ref propvar)) - (-> (ref tmpvar))))))))))) - ((predec (ref ,foo)) - (let ((v (ghil-var-for-set! e foo))) - (-> (begin - (list - (-> (set v - (-> (inline 'sub - (list (-> (ref v)) - (-> (quote 1))))))) - (-> (ref v))))))) - ((predec (pref ,obj ,prop)) - (let1 (comp obj e) - (lambda (objvar) - (begin1 (-> (inline 'sub - (list (@impl pget - (list (-> (ref objvar)) - (-> (quote prop)))) - (-> (quote 1))))) - (lambda (tmpvar) - (@impl pput - (list (-> (ref objvar)) - (-> (quote prop)) - (-> (ref tmpvar))))))))) - ((predec (aref ,obj ,prop)) - (let1 (comp obj e) - (lambda (objvar) - (let1 (comp prop e) - (lambda (propvar) - (begin1 (-> (inline 'sub - (list (@impl pget - (list (-> (ref objvar)) - (-> (ref propvar)))) - (-> (quote 1))))) - (lambda (tmpvar) - (@impl pput - (list (-> (ref objvar)) - (-> (ref propvar)) - (-> (ref tmpvar))))))))))) - ((ref ,id) - (-> (ref (ghil-var-for-ref! e id)))) - ((var . ,forms) - (-> (begin - (map (lambda (form) - (pmatch form - ((,x ,y) - (-> (define (ghil-var-define! (ghil-env-parent e) x) - (comp y e)))) - ((,x) - (-> (define (ghil-var-define! (ghil-env-parent e) x) - (@implv *undefined*)))) - (else (error "bad var form" form)))) - forms)))) - ((begin . ,forms) - (-> (begin - (map (lambda (x) (comp x e)) forms)))) - ((lambda ,formals ,body) - (call-with-ghil-environment e '(%args) - (lambda (e vars) - (-> (lambda vars #t '() - (comp-body env l body formals '%args)))))) - ((call/this ,obj ,prop ,args) - (@impl call/this* - (list obj - (-> (lambda '() #f '() - (-> (call (@impl pget (list obj prop)) - args))))))) - ((call (pref ,obj ,prop) ,args) - (comp `(call/this ,(comp obj e) - ,(-> (quote prop)) - ,(map (lambda (x) (comp x e)) args)) - e)) - ((call (aref ,obj ,prop) ,args) - (comp `(call/this ,(comp obj e) - ,(comp prop e) - ,(map (lambda (x) (comp x e)) args)) - e)) - ((call ,proc ,args) - (-> (call (comp proc e) - (map (lambda (x) (comp x e)) args)))) - ((return ,expr) - (-> (inline 'return - (list (comp expr e))))) - ((array . ,args) - (@impl new-array - (map (lambda (x) (comp x e)) args))) - ((object . ,args) - (@impl new-object - (map (lambda (x) - (pmatch x - ((,prop ,val) - (-> (inline 'cons - (list (-> (quote prop)) - (comp val e))))) - (else - (error "bad prop-val pair" x)))) - args))) - ((pref ,obj ,prop) - (@impl pget - (list (comp obj e) - (-> (quote prop))))) - ((aref ,obj ,index) - (@impl pget - (list (comp obj e) - (comp index e)))) - ((= (ref ,name) ,val) - (let ((v (ghil-var-for-set! e name))) - (-> (begin - (list (-> (set v (comp val e))) - (-> (ref v))))))) - ((= (pref ,obj ,prop) ,val) - (@impl pput - (list (comp obj e) - (-> (quote prop)) - (comp val e)))) - ((= (aref ,obj ,prop) ,val) - (@impl pput - (list (comp obj e) - (comp prop e) - (comp val e)))) - ((+= ,what ,val) - (comp `(= ,what (+ ,what ,val)) e)) - ((-= ,what ,val) - (comp `(= ,what (- ,what ,val)) e)) - ((/= ,what ,val) - (comp `(= ,what (/ ,what ,val)) e)) - ((*= ,what ,val) - (comp `(= ,what (* ,what ,val)) e)) - ((%= ,what ,val) - (comp `(= ,what (% ,what ,val)) e)) - ((>>= ,what ,val) - (comp `(= ,what (>> ,what ,val)) e)) - ((<<= ,what ,val) - (comp `(= ,what (<< ,what ,val)) e)) - ((>>>= ,what ,val) - (comp `(= ,what (>>> ,what ,val)) e)) - ((&= ,what ,val) - (comp `(= ,what (& ,what ,val)) e)) - ((bor= ,what ,val) - (comp `(= ,what (bor ,what ,val)) e)) - ((^= ,what ,val) - (comp `(= ,what (^ ,what ,val)) e)) - ((new ,what ,args) - (@impl new - (map (lambda (x) (comp x e)) - (cons what args)))) - ((delete (pref ,obj ,prop)) - (@impl pdel - (list (comp obj e) - (-> (quote prop))))) - ((delete (aref ,obj ,prop)) - (@impl pdel - (list (comp obj e) - (comp prop e)))) - ((void ,expr) - (-> (begin - (list (comp expr e) - (@implv *undefined*))))) - ((typeof ,expr) - (@impl typeof - (list (comp expr e)))) - ((do ,statement ,test) - (call-with-ghil-bindings e '(%loop %continue) - (lambda (vars) - (-> (bind vars - (list (call-with-ghil-environment e '() - (lambda (e _) - (-> (lambda '() #f '() - (-> (begin - (list (comp statement e) - (-> (call - (-> (ref (ghil-var-for-ref! e '%continue))) - '()))))))))) - (call-with-ghil-environment e '() - (lambda (e _) - (-> (lambda '() #f '() - (-> (if (@impl ->boolean (list (comp test e))) - (-> (call - (-> (ref (ghil-var-for-ref! e '%loop))) - '())) - (@implv *undefined*)))))))) - (-> (call (-> (ref (car vars))) '()))))))) - ((while ,test ,statement) - (call-with-ghil-bindings e '(%continue) - (lambda (vars) - (-> (begin - (list - (-> (set (car vars) - (call-with-ghil-environment e '() - (lambda (e _) - (-> (lambda '() #f '() - (-> (if (@impl ->boolean (list (comp test e))) - (-> (begin - (list (comp statement e) - (-> (call - (-> (ref (ghil-var-for-ref! e '%continue))) - '()))))) - (@implv *undefined*))))))))) - (-> (call (-> (ref (car vars))) '())))))))) - ((for ,init ,test ,inc ,statement) - (call-with-ghil-bindings e '(%continue) - (lambda (vars) - (-> (begin - (list - (comp (or init '(begin)) e) - (-> (set (car vars) - (call-with-ghil-environment e '() - (lambda (e _) - (-> (lambda '() #f '() - (-> (if (if test - (@impl ->boolean (list (comp test e))) - (comp 'true e)) - (-> (begin - (list (comp statement e) - (comp (or inc '(begin)) e) - (-> (call - (-> (ref (ghil-var-for-ref! e '%continue))) - '()))))) - (@implv *undefined*))))))))) - (-> (call (-> (ref (car vars))) '())))))))) - ((for-in ,var ,object ,statement) - (call-with-ghil-bindings e '(%continue %enum) - (lambda (vars) - (-> (begin - (list - (-> (set (car vars) - (call-with-ghil-environment e '() - (lambda (e _) - (-> (lambda '() #f '() - (-> (if (@impl ->boolean - (list (@impl pget - (list (-> (ref (ghil-var-for-ref! e '%enum))) - (-> (quote 'length)))))) - (-> (begin - (list - (comp `(= ,var (call/this ,(-> (ref (ghil-var-for-ref! e '%enum))) - ,(-> (quote 'pop)) - ())) - e) - (comp statement e) - (-> (call (-> (ref (ghil-var-for-ref! e '%continue))) - '()))))) - (@implv *undefined*))))))))) - (-> (set (cadr vars) - (@impl make-enumerator (list (comp object e))))) - (-> (call (-> (ref (car vars))) '())))))))) - ((break) - (let ((var (ghil-var-for-ref! e '%continue))) - (if (and (ghil-env? (ghil-var-env var)) - (eq? (ghil-var-env var) (ghil-env-parent e))) - (-> (inline 'return (@implv *undefined*))) - (error "bad break, yo")))) - ((continue) - (let ((var (ghil-var-for-ref! e '%continue))) - (if (and (ghil-env? (ghil-var-env var)) - (eq? (ghil-var-env var) (ghil-env-parent e))) - (-> (inline 'goto/args (list (-> (ref var))))) - (error "bad continue, yo")))) - ((block ,x) - (comp x e)) - (else - (error "compilation not yet implemented:" x))))) - -(define (comp-body e l body formals %args) - (define (process) - (let lp ((in body) (out '()) (rvars (reverse formals))) - (pmatch in - (((var (,x) . ,morevars) . ,rest) - (lp `((var . ,morevars) . ,rest) - out - (if (memq x rvars) rvars (cons x rvars)))) - (((var (,x ,y) . ,morevars) . ,rest) - (lp `((var . ,morevars) . ,rest) - `((= (ref ,x) ,y) . ,out) - (if (memq x rvars) rvars (cons x rvars)))) - (((var) . ,rest) - (lp rest out rvars)) - ((,x . ,rest) (guard (and (pair? x) (eq? (car x) 'lambda))) - (lp rest - (cons x out) - rvars)) - ((,x . ,rest) (guard (pair? x)) - (receive (sub-out rvars) - (lp x '() rvars) - (lp rest - (cons sub-out out) - rvars))) - ((,x . ,rest) - (lp rest - (cons x out) - rvars)) - (() - (values (reverse! out) - rvars))))) - (receive (out rvars) - (process) - (call-with-ghil-bindings e (reverse rvars) - (lambda (vars) - (let ((%argv (assq-ref (ghil-env-table e) %args))) - (-> (begin - `(,@(map - (lambda (f) - (-> (if (-> (inline 'null? - (list (-> (ref %argv))))) - (-> (begin '())) - (-> (begin - (list (-> (set (ghil-var-for-ref! e f) - (-> (inline 'car - (list (-> (ref %argv))))))) - (-> (set %argv - (-> (inline 'cdr - (list (-> (ref %argv))))))))))))) - formals) - ;; fixme: here check for too many args - ,(comp out e))))))))) diff --git a/module/language/ecmascript/compile-tree-il.scm b/module/language/ecmascript/compile-tree-il.scm new file mode 100644 index 000000000..88f3db76f --- /dev/null +++ b/module/language/ecmascript/compile-tree-il.scm @@ -0,0 +1,549 @@ +;;; ECMAScript for Guile + +;; Copyright (C) 2009 Free Software Foundation, Inc. + +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +;;; Code: + +(define-module (language ecmascript compile-tree-il) + #:use-module (language tree-il) + #:use-module (ice-9 receive) + #:use-module (system base pmatch) + #:use-module (srfi srfi-1) + #:export (compile-tree-il)) + +(define-syntax -> + (syntax-rules () + ((_ (type arg ...)) + `(type ,arg ...)))) + +(define-syntax @implv + (syntax-rules () + ((_ sym) + (-> (module-ref '(language ecmascript impl) 'sym #t))))) + +(define-syntax @impl + (syntax-rules () + ((_ sym arg ...) + (-> (apply (@implv sym) arg ...))))) + +(define (empty-lexical-environment) + '()) + +(define (econs name gensym env) + (acons name gensym env)) + +(define (lookup name env) + (or (assq-ref env name) + (-> (toplevel name)))) + +(define (compile-tree-il exp env opts) + (values + (parse-tree-il (comp exp (empty-lexical-environment))) + env + env)) + +(define (location x) + (and (pair? x) + (let ((props (source-properties x))) + (and (not (null? props)) + props)))) + +;; for emacs: +;; (put 'pmatch/source 'scheme-indent-function 1) + +(define-syntax pmatch/source + (syntax-rules () + ((_ x clause ...) + (let ((x x)) + (let ((res (pmatch x + clause ...))) + (let ((loc (location x))) + (if loc + (set-source-properties! res (location x)))) + res))))) + +(define (comp x e) + (let ((l (location x))) + (define (let1 what proc) + (let ((sym (gensym))) + (-> (let (list sym) (list sym) (list what) + (proc sym))))) + (define (begin1 what proc) + (let1 what (lambda (v) + (-> (begin (proc v) + (-> (lexical v v))))))) + (pmatch/source x + (null + ;; FIXME, null doesn't have much relation to EOL... + (-> (const '()))) + (true + (-> (const #t))) + (false + (-> (const #f))) + ((number ,num) + (-> (const num))) + ((string ,str) + (-> (const str))) + (this + (@impl get-this '())) + ((+ ,a) + (-> (apply (-> (primitive '+)) + (@impl ->number (comp a e)) + (-> (const 0))))) + ((- ,a) + (-> (apply (-> (primitive '-)) (-> (const 0)) (comp a e)))) + ((~ ,a) + (@impl bitwise-not (comp a e))) + ((! ,a) + (@impl logical-not (comp a e))) + ((+ ,a ,b) + (-> (apply (-> (primitive '+)) (comp a e) (comp b e)))) + ((- ,a ,b) + (-> (apply (-> (primitive '-)) (comp a e) (comp b e)))) + ((/ ,a ,b) + (-> (apply (-> (primitive '/)) (comp a e) (comp b e)))) + ((* ,a ,b) + (-> (apply (-> (primitive '*)) (comp a e) (comp b e)))) + ((% ,a ,b) + (@impl mod (comp a e) (comp b e))) + ((<< ,a ,b) + (@impl shift (comp a e) (comp b e))) + ((>> ,a ,b) + (@impl shift (comp a e) (comp `(- ,b) e))) + ((< ,a ,b) + (-> (apply (-> (primitive '<)) (comp a e) (comp b e)))) + ((<= ,a ,b) + (-> (apply (-> (primitive '<=)) (comp a e) (comp b e)))) + ((> ,a ,b) + (-> (apply (-> (primitive '>)) (comp a e) (comp b e)))) + ((>= ,a ,b) + (-> (apply (-> (primitive '>=)) (comp a e) (comp b e)))) + ((in ,a ,b) + (@impl has-property? (comp a e) (comp b e))) + ((== ,a ,b) + (-> (apply (-> (primitive 'equal?)) (comp a e) (comp b e)))) + ((!= ,a ,b) + (-> (apply (-> (primitive 'not)) + (-> (apply (-> (primitive 'equal?)) + (comp a e) (comp b e)))))) + ((=== ,a ,b) + (-> (apply (-> (primitive 'eqv?)) (comp a e) (comp b e)))) + ((!== ,a ,b) + (-> (apply (-> (primitive 'not)) + (-> (apply (-> (primitive 'eqv?)) + (comp a e) (comp b e)))))) + ((& ,a ,b) + (@impl band (comp a e) (comp b e))) + ((^ ,a ,b) + (@impl bxor (comp a e) (comp b e))) + ((bor ,a ,b) + (@impl bior (comp a e) (comp b e))) + ((and ,a ,b) + (-> (if (@impl ->boolean (comp a e)) + (comp b e) + (-> (const #f))))) + ((or ,a ,b) + (let1 (comp a e) + (lambda (v) + (-> (if (@impl ->boolean (-> (lexical v v))) + (-> (lexical v v)) + (comp b e)))))) + ((if ,test ,then ,else) + (-> (if (@impl ->boolean (comp test e)) + (comp then e) + (comp else e)))) + ((if ,test ,then ,else) + (-> (if (@impl ->boolean (comp test e)) + (comp then e) + (@implv *undefined*)))) + ((postinc (ref ,foo)) + (begin1 (comp `(ref ,foo) e) + (lambda (var) + (-> (set! (lookup foo e) + (-> (apply (-> (primitive '+)) + (-> (lexical var var)) + (-> (const 1))))))))) + ((postinc (pref ,obj ,prop)) + (let1 (comp obj e) + (lambda (objvar) + (begin1 (@impl pget + (-> (lexical objvar objvar)) + (-> (const prop))) + (lambda (tmpvar) + (@impl pput + (-> (lexical objvar objvar)) + (-> (const prop)) + (-> (apply (-> (primitive '+)) + (-> (lexical tmpvar tmpvar)) + (-> (const 1)))))))))) + ((postinc (aref ,obj ,prop)) + (let1 (comp obj e) + (lambda (objvar) + (let1 (comp prop e) + (lambda (propvar) + (begin1 (@impl pget + (-> (lexical objvar objvar)) + (-> (lexical propvar propvar))) + (lambda (tmpvar) + (@impl pput + (-> (lexical objvar objvar)) + (-> (lexical propvar propvar)) + (-> (apply (-> (primitive '+)) + (-> (lexical tmpvar tmpvar)) + (-> (const 1)))))))))))) + ((postdec (ref ,foo)) + (begin1 (comp `(ref ,foo) e) + (lambda (var) + (-> (set (lookup foo e) + (-> (apply (-> (primitive '-)) + (-> (lexical var var)) + (-> (const 1))))))))) + ((postdec (pref ,obj ,prop)) + (let1 (comp obj e) + (lambda (objvar) + (begin1 (@impl pget + (-> (lexical objvar objvar)) + (-> (const prop))) + (lambda (tmpvar) + (@impl pput + (-> (lexical objvar objvar)) + (-> (const prop)) + (-> (apply (-> (primitive '-)) + (-> (lexical tmpvar tmpvar)) + (-> (const 1)))))))))) + ((postdec (aref ,obj ,prop)) + (let1 (comp obj e) + (lambda (objvar) + (let1 (comp prop e) + (lambda (propvar) + (begin1 (@impl pget + (-> (lexical objvar objvar)) + (-> (lexical propvar propvar))) + (lambda (tmpvar) + (@impl pput + (-> (lexical objvar objvar)) + (-> (lexical propvar propvar)) + (-> (inline + '- (-> (lexical tmpvar tmpvar)) + (-> (const 1)))))))))))) + ((preinc (ref ,foo)) + (let ((v (lookup foo e))) + (-> (begin + (-> (set! v + (-> (apply (-> (primitive '+)) + v + (-> (const 1)))))) + v)))) + ((preinc (pref ,obj ,prop)) + (let1 (comp obj e) + (lambda (objvar) + (begin1 (-> (apply (-> (primitive '+)) + (@impl pget + (-> (lexical objvar objvar)) + (-> (const prop))) + (-> (const 1)))) + (lambda (tmpvar) + (@impl pput (-> (lexical objvar objvar)) + (-> (const prop)) + (-> (lexical tmpvar tmpvar)))))))) + ((preinc (aref ,obj ,prop)) + (let1 (comp obj e) + (lambda (objvar) + (let1 (comp prop e) + (lambda (propvar) + (begin1 (-> (apply (-> (primitive '+)) + (@impl pget + (-> (lexical objvar objvar)) + (-> (lexical propvar propvar))) + (-> (const 1)))) + (lambda (tmpvar) + (@impl pput + (-> (lexical objvar objvar)) + (-> (lexical propvar propvar)) + (-> (lexical tmpvar tmpvar)))))))))) + ((predec (ref ,foo)) + (let ((v (lookup foo e))) + (-> (begin + (-> (set! v + (-> (apply (-> (primitive '-)) + v + (-> (const 1)))))) + v)))) + ((predec (pref ,obj ,prop)) + (let1 (comp obj e) + (lambda (objvar) + (begin1 (-> (apply (-> (primitive '-)) + (@impl pget + (-> (lexical objvar objvar)) + (-> (const prop))) + (-> (const 1)))) + (lambda (tmpvar) + (@impl pput + (-> (lexical objvar objvar)) + (-> (const prop)) + (-> (lexical tmpvar tmpvar)))))))) + ((predec (aref ,obj ,prop)) + (let1 (comp obj e) + (lambda (objvar) + (let1 (comp prop e) + (lambda (propvar) + (begin1 (-> (apply (-> (primitive '-)) + (@impl pget + (-> (lexical objvar objvar)) + (-> (lexical propvar propvar))) + (-> (const 1)))) + (lambda (tmpvar) + (@impl pput + (-> (lexical objvar objvar)) + (-> (lexical propvar propvar)) + (-> (lexical tmpvar tmpvar)))))))))) + ((ref ,id) + (lookup id e)) + ((var . ,forms) + (-> (begin + (map (lambda (form) + (pmatch form + ((,x ,y) + (-> (define x (comp y e)))) + ((,x) + (-> (define x (@implv *undefined*)))) + (else (error "bad var form" form)))) + forms)))) + ((begin . ,forms) + `(begin ,@(map (lambda (x) (comp x e)) forms))) + ((lambda ,formals ,body) + (let ((%args (gensym "%args "))) + (-> (lambda '%args %args '() + (comp-body (econs '%args %args e) body formals '%args))))) + ((call/this ,obj ,prop . ,args) + (@impl call/this* + obj + (-> (lambda '() '() '() + `(apply ,(@impl pget obj prop) ,@args))))) + ((call (pref ,obj ,prop) ,args) + (comp `(call/this ,(comp obj e) + ,(-> (const prop)) + ,@(map (lambda (x) (comp x e)) args)) + e)) + ((call (aref ,obj ,prop) ,args) + (comp `(call/this ,(comp obj e) + ,(comp prop e) + ,@(map (lambda (x) (comp x e)) args)) + e)) + ((call ,proc ,args) + `(apply ,(comp proc e) + ,@(map (lambda (x) (comp x e)) args))) + ((return ,expr) + (-> (apply (-> (primitive 'return)) + (comp expr e)))) + ((array . ,args) + `(apply ,(@implv new-array) + ,@(map (lambda (x) (comp x e)) args))) + ((object . ,args) + (@impl new-object + (map (lambda (x) + (pmatch x + ((,prop ,val) + (-> (apply (-> (primitive 'cons)) + (-> (const prop)) + (comp val e)))) + (else + (error "bad prop-val pair" x)))) + args))) + ((pref ,obj ,prop) + (@impl pget + (comp obj e) + (-> (const prop)))) + ((aref ,obj ,index) + (@impl pget + (comp obj e) + (comp index e))) + ((= (ref ,name) ,val) + (let ((v (lookup name e))) + (-> (begin + (-> (set! v (comp val e))) + v)))) + ((= (pref ,obj ,prop) ,val) + (@impl pput + (comp obj e) + (-> (const prop)) + (comp val e))) + ((= (aref ,obj ,prop) ,val) + (@impl pput + (comp obj e) + (comp prop e) + (comp val e))) + ((+= ,what ,val) + (comp `(= ,what (+ ,what ,val)) e)) + ((-= ,what ,val) + (comp `(= ,what (- ,what ,val)) e)) + ((/= ,what ,val) + (comp `(= ,what (/ ,what ,val)) e)) + ((*= ,what ,val) + (comp `(= ,what (* ,what ,val)) e)) + ((%= ,what ,val) + (comp `(= ,what (% ,what ,val)) e)) + ((>>= ,what ,val) + (comp `(= ,what (>> ,what ,val)) e)) + ((<<= ,what ,val) + (comp `(= ,what (<< ,what ,val)) e)) + ((>>>= ,what ,val) + (comp `(= ,what (>>> ,what ,val)) e)) + ((&= ,what ,val) + (comp `(= ,what (& ,what ,val)) e)) + ((bor= ,what ,val) + (comp `(= ,what (bor ,what ,val)) e)) + ((^= ,what ,val) + (comp `(= ,what (^ ,what ,val)) e)) + ((new ,what ,args) + (@impl new + (map (lambda (x) (comp x e)) + (cons what args)))) + ((delete (pref ,obj ,prop)) + (@impl pdel + (comp obj e) + (-> (const prop)))) + ((delete (aref ,obj ,prop)) + (@impl pdel + (comp obj e) + (comp prop e))) + ((void ,expr) + (-> (begin + (comp expr e) + (@implv *undefined*)))) + ((typeof ,expr) + (@impl typeof + (comp expr e))) + ((do ,statement ,test) + (let ((%loop (gensym "%loop ")) + (%continue (gensym "%continue "))) + (let ((e (econs '%loop %loop (econs '%continue %continue e)))) + (-> (letrec '(%loop %continue) (list %loop %continue) + (list (-> (lambda '() '() '() + (-> (begin + (comp statement e) + (-> (apply (-> (lexical '%continue %continue))) + ))))) + + (-> (lambda '() '() '() + (-> (if (@impl ->boolean (comp test e)) + (-> (apply (-> (lexical '%loop %loop)))) + (@implv *undefined*)))))) + (-> (apply (-> (lexical '%loop %loop))))))))) + ((while ,test ,statement) + (let ((%continue (gensym "%continue "))) + (let ((e (econs '%continue %continue e))) + (-> (letrec '(%continue) (list %continue) + (list (-> (lambda '() '() '() + (-> (if (@impl ->boolean (comp test e)) + (-> (begin (comp statement e) + (-> (apply (-> (lexical '%continue %continue)))))) + (@implv *undefined*)))))) + (-> (apply (-> (lexical '%continue %continue))))))))) + + ((for ,init ,test ,inc ,statement) + (let ((%continue (gensym "%continue "))) + (let ((e (econs '%continue %continue e))) + (-> (letrec '(%continue) (list %continue) + (list (-> (lambda '() '() '() + (-> (if (if test + (@impl ->boolean (comp test e)) + (comp 'true e)) + (-> (begin (comp statement e) + (comp (or inc '(begin)) e) + (-> (apply (-> (lexical '%continue %continue)))))) + (@implv *undefined*)))))) + (-> (begin (comp (or init '(begin)) e) + (-> (apply (-> (lexical '%continue %continue))))))))))) + + ((for-in ,var ,object ,statement) + (let ((%enum (gensym "%enum ")) + (%continue (gensym "%continue "))) + (let ((e (econs '%enum %enum (econs '%continue %continue e)))) + (-> (letrec '(%enum %continue) (list %enum %continue) + (list (@impl make-enumerator (comp object e)) + (-> (lambda '() '() '() + (-> (if (@impl ->boolean + (@impl pget + (-> (lexical '%enum %enum)) + (-> (const 'length)))) + (-> (begin + (comp `(= ,var (call/this ,(-> (lexical '%enum %enum)) + ,(-> (const 'pop)))) + e) + (comp statement e) + (-> (apply (-> (lexical '%continue %continue)))))) + (@implv *undefined*)))))) + (-> (apply (-> (lexical '%continue %continue))))))))) + + ((block ,x) + (comp x e)) + (else + (error "compilation not yet implemented:" x))))) + +(define (comp-body e body formals %args) + (define (process) + (let lp ((in body) (out '()) (rvars (reverse formals))) + (pmatch in + (((var (,x) . ,morevars) . ,rest) + (lp `((var . ,morevars) . ,rest) + out + (if (memq x rvars) rvars (cons x rvars)))) + (((var (,x ,y) . ,morevars) . ,rest) + (lp `((var . ,morevars) . ,rest) + `((= (ref ,x) ,y) . ,out) + (if (memq x rvars) rvars (cons x rvars)))) + (((var) . ,rest) + (lp rest out rvars)) + ((,x . ,rest) (guard (and (pair? x) (eq? (car x) 'lambda))) + (lp rest + (cons x out) + rvars)) + ((,x . ,rest) (guard (pair? x)) + (receive (sub-out rvars) + (lp x '() rvars) + (lp rest + (cons sub-out out) + rvars))) + ((,x . ,rest) + (lp rest + (cons x out) + rvars)) + (() + (values (reverse! out) + rvars))))) + (receive (out rvars) + (process) + (let* ((names (reverse rvars)) + (syms (map (lambda (x) + (gensym (string-append (symbol->string x) " "))) + names)) + (e (fold acons e names syms))) + (let ((%argv (lookup %args e))) + (let lp ((names names) (syms syms)) + (if (null? names) + ;; fixme: here check for too many args + (comp out e) + (-> (let (list (car names)) (list (car syms)) + (list (-> (if (-> (apply (-> (primitive 'null?)) %argv)) + (-> (@implv *undefined*)) + (-> (let1 (-> (apply (-> (primitive 'car)) %argv)) + (lambda (v) + (-> (set! %argv + (-> (apply (-> (primitive 'cdr)) %argv)))) + (-> (lexical v v)))))))) + (lp (cdr names) (cdr syms)))))))))) diff --git a/module/language/ecmascript/function.scm b/module/language/ecmascript/function.scm index 1e2d726ca..710c5cb1c 100644 --- a/module/language/ecmascript/function.scm +++ b/module/language/ecmascript/function.scm @@ -2,20 +2,19 @@ ;; Copyright (C) 2009 Free Software Foundation, Inc. -;; 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 2, 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 COPYING. If not, write to -;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Code: diff --git a/module/language/ecmascript/impl.scm b/module/language/ecmascript/impl.scm index be4c751cb..27c077aed 100644 --- a/module/language/ecmascript/impl.scm +++ b/module/language/ecmascript/impl.scm @@ -2,20 +2,19 @@ ;; Copyright (C) 2009 Free Software Foundation, Inc. -;; 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 2, 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 COPYING. If not, write to -;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Code: diff --git a/module/language/ecmascript/parse-lalr.scm b/module/language/ecmascript/parse-lalr.scm index 6378d087c..b702511ca 100644 --- a/module/language/ecmascript/parse-lalr.scm +++ b/module/language/ecmascript/parse-lalr.scm @@ -2,18 +2,19 @@ ;; Copyright (C) 1984,1989,1990 Free Software Foundation, Inc. ;; Copyright (C) 1996-2002 Dominique Boucher -;; 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 . +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;; ---------------------------------------------------------------------- ;; diff --git a/module/language/ecmascript/parse.scm b/module/language/ecmascript/parse.scm index 169c992fd..ce731a736 100644 --- a/module/language/ecmascript/parse.scm +++ b/module/language/ecmascript/parse.scm @@ -2,20 +2,19 @@ ;; Copyright (C) 2009 Free Software Foundation, Inc. -;; 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 2, 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 COPYING. If not, write to -;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Code: diff --git a/module/language/ecmascript/spec.scm b/module/language/ecmascript/spec.scm index 550a0b734..7a1ea465c 100644 --- a/module/language/ecmascript/spec.scm +++ b/module/language/ecmascript/spec.scm @@ -2,27 +2,26 @@ ;; Copyright (C) 2009 Free Software Foundation, Inc. -;; 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 2, 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 COPYING. If not, write to -;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Code: (define-module (language ecmascript spec) #:use-module (system base language) #:use-module (language ecmascript parse) - #:use-module (language ecmascript compile-ghil) + #:use-module (language ecmascript compile-tree-il) #:export (ecmascript)) ;;; @@ -33,8 +32,7 @@ #:title "Guile ECMAScript" #:version "3.0" #:reader (lambda () (read-ecmascript/1 (current-input-port))) - #:read-file read-ecmascript - #:compilers `((ghil . ,compile-ghil)) + #:compilers `((tree-il . ,compile-tree-il)) ;; a pretty-printer would be interesting. #:printer write ) diff --git a/module/language/ecmascript/tokenize.scm b/module/language/ecmascript/tokenize.scm index 2beda23b7..1b6a7eeaf 100644 --- a/module/language/ecmascript/tokenize.scm +++ b/module/language/ecmascript/tokenize.scm @@ -2,20 +2,19 @@ ;; Copyright (C) 2009 Free Software Foundation, Inc. -;; 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 2, 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 COPYING. If not, write to -;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Code: @@ -366,7 +365,7 @@ . ,(cdar puncs)))))) (lp nodes (cdr puncs)))) (else - (lp (cons `(,(string-ref (caar puncs) 0) #f) nodes) + (lp (cons (list (string-ref (caar puncs) 0) #f) nodes) puncs)))))) (lambda (port) (let lp ((c (peek-char port)) (tree punc-tree) (candidate #f)) diff --git a/module/language/elisp/spec.scm b/module/language/elisp/spec.scm index a35c44112..617e4e3c5 100644 --- a/module/language/elisp/spec.scm +++ b/module/language/elisp/spec.scm @@ -2,20 +2,19 @@ ;; Copyright (C) 2001 Free Software Foundation, Inc. -;; 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 2, 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 COPYING. If not, write to -;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Code: diff --git a/module/language/ghil.scm b/module/language/ghil.scm index 00a2c9afd..84cc83de5 100644 --- a/module/language/ghil.scm +++ b/module/language/ghil.scm @@ -2,20 +2,19 @@ ;; Copyright (C) 2001 Free Software Foundation, Inc. -;; 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 2, 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 COPYING. If not, write to -;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Code: @@ -432,7 +431,10 @@ (( env loc obj) `(,'quote ,obj)) (( env loc exp) - `(,'quasiquote ,(map unparse-ghil exp))) + `(,'quasiquote ,(let lp ((x exp)) + (cond ((struct? x) (unparse-ghil x)) + ((pair? x) (cons (lp (car x)) (lp (cdr x)))) + (else x))))) (( env loc exp) `(,'unquote ,(unparse-ghil exp))) (( env loc exp) diff --git a/module/language/ghil/compile-glil.scm b/module/language/ghil/compile-glil.scm index c816b0e6c..47e15c797 100644 --- a/module/language/ghil/compile-glil.scm +++ b/module/language/ghil/compile-glil.scm @@ -2,25 +2,24 @@ ;; Copyright (C) 2001 Free Software Foundation, Inc. -;; 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 2, 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 COPYING. If not, write to -;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Code: (define-module (language ghil compile-glil) - #:use-syntax (system base syntax) + #:use-module (system base syntax) #:use-module (language glil) #:use-module (language ghil) #:use-module (ice-9 common-list) @@ -29,7 +28,8 @@ (define (compile-glil x e opts) (if (memq #:O opts) (set! x (optimize x))) (values (codegen x) - (and e (cons (car e) (cddr e))))) + (and e (cons (car e) (cddr e))) + e)) ;;; @@ -186,7 +186,7 @@ (define (make-glil-var op env var) (case (ghil-var-kind var) ((argument) - (make-glil-argument op (ghil-var-index var))) + (make-glil-local op (ghil-var-index var))) ((local) (make-glil-local op (ghil-var-index var))) ((external) @@ -216,7 +216,9 @@ (set! stack (cons code stack)) (if loc (set! stack (cons (make-glil-source loc) stack)))) (define (var->binding var) - (list (ghil-var-name var) (ghil-var-kind var) (ghil-var-index var))) + (list (ghil-var-name var) (let ((kind (ghil-var-kind var))) + (case kind ((argument) 'local) (else kind))) + (ghil-var-index var))) (define (push-bindings! loc vars) (if (not (null? vars)) (push-code! loc (make-glil-bind (map var->binding vars))))) @@ -495,7 +497,7 @@ (locs (pick (lambda (v) (eq? (ghil-var-kind v) 'local)) evars)) (exts (pick (lambda (v) (eq? (ghil-var-kind v) 'external)) evars)) (nargs (allocate-indices-linearly! vars)) - (nlocs (allocate-locals! locs body)) + (nlocs (allocate-locals! locs body nargs)) (nexts (allocate-indices-linearly! exts))) ;; meta bindings (push-bindings! #f vars) @@ -508,7 +510,7 @@ (let ((v (car l))) (case (ghil-var-kind v) ((external) - (push-code! #f (make-glil-argument 'ref n)) + (push-code! #f (make-glil-local 'ref n)) (push-code! #f (make-glil-external 'set 0 (ghil-var-index v))))))) ;; compile body (comp body #t #f) @@ -522,8 +524,8 @@ ((null? l) n) (let ((v (car l))) (set! (ghil-var-index v) n)))) -(define (allocate-locals! vars body) - (let ((free '()) (nlocs 0)) +(define (allocate-locals! vars body nargs) + (let ((free '()) (nlocs nargs)) (define (allocate! var) (cond ((pair? free) diff --git a/module/language/ghil/spec.scm b/module/language/ghil/spec.scm index ee574b50b..f2bc19b61 100644 --- a/module/language/ghil/spec.scm +++ b/module/language/ghil/spec.scm @@ -2,20 +2,19 @@ ;; Copyright (C) 2001 Free Software Foundation, Inc. -;; 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 2, 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 COPYING. If not, write to -;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Code: @@ -34,11 +33,30 @@ (lambda (env vars) (make-ghil-lambda env #f vars #f '() (parse-ghil env x))))) +(define (join exps env) + (if (or-map (lambda (x) + (or (not (ghil-lambda? x)) + (ghil-lambda-rest x) + (memq 'argument + (map ghil-var-kind + (ghil-env-variables (ghil-lambda-env x)))))) + exps) + (error "GHIL expressions to join must be thunks")) + + (let ((env (make-ghil-env env '() + (apply append + (map ghil-env-variables + (map ghil-lambda-env exps)))))) + (make-ghil-lambda env #f '() #f '() + (make-ghil-begin env #f + (map ghil-lambda-body exps))))) + (define-language ghil #:title "Guile High Intermediate Language (GHIL)" #:version "0.3" #:reader read #:printer write-ghil #:parser parse + #:joiner join #:compilers `((glil . ,compile-glil)) ) diff --git a/module/language/glil.scm b/module/language/glil.scm index 01b680194..0777073f6 100644 --- a/module/language/glil.scm +++ b/module/language/glil.scm @@ -1,21 +1,20 @@ ;;; Guile Low Intermediate Language -;; Copyright (C) 2001 Free Software Foundation, Inc. +;; Copyright (C) 2001, 2009 Free Software Foundation, Inc. -;; 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 2, 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 COPYING. If not, write to -;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Code: @@ -25,9 +24,9 @@ #:use-module ((srfi srfi-1) #:select (fold)) #:export ( make-glil-program glil-program? - glil-program-nargs glil-program-nrest glil-program-nlocs glil-program-nexts - glil-program-meta glil-program-body glil-program-closure-level - + glil-program-nargs glil-program-nrest glil-program-nlocs + glil-program-meta glil-program-body + make-glil-bind glil-bind? glil-bind-vars @@ -44,14 +43,8 @@ make-glil-const glil-const? glil-const-obj - make-glil-argument glil-argument? - glil-argument-op glil-argument-index - - make-glil-local glil-local? - glil-local-op glil-local-index - - make-glil-external glil-external? - glil-external-op glil-external-depth glil-external-index + make-glil-lexical glil-lexical? + glil-lexical-local? glil-lexical-boxed? glil-lexical-op glil-lexical-index make-glil-toplevel glil-toplevel? glil-toplevel-op glil-toplevel-name @@ -78,7 +71,7 @@ (define-type ( #:printer print-glil) ;; Meta operations - ( nargs nrest nlocs nexts meta body (closure-level #f)) + ( nargs nrest nlocs meta body) ( vars) ( vars rest) () @@ -87,9 +80,7 @@ () ( obj) ;; Variables - ( op index) - ( op index) - ( op depth index) + ( local? boxed? op index) ( op name) ( op mod name public?) ;; Controls @@ -98,40 +89,23 @@ ( inst nargs) ( nargs ra)) -(define (compute-closure-level body) - (fold (lambda (x ret) - (record-case x - (( closure-level) (max ret closure-level)) - (( depth) (max ret depth)) - (else ret))) - 0 body)) - -(define %make-glil-program make-glil-program) -(define (make-glil-program . args) - (let ((prog (apply %make-glil-program args))) - (if (not (glil-program-closure-level prog)) - (set! (glil-program-closure-level prog) - (compute-closure-level (glil-program-body prog)))) - prog)) - + (define (parse-glil x) (pmatch x - ((program ,nargs ,nrest ,nlocs ,nexts ,meta . ,body) - (make-glil-program nargs nrest nlocs nexts meta (map parse-glil body))) + ((program ,nargs ,nrest ,nlocs ,meta . ,body) + (make-glil-program nargs nrest nlocs meta (map parse-glil body))) ((bind . ,vars) (make-glil-bind vars)) ((mv-bind ,vars ,rest) (make-glil-mv-bind vars rest)) ((unbind) (make-glil-unbind)) ((source ,props) (make-glil-source props)) ((void) (make-glil-void)) ((const ,obj) (make-glil-const obj)) - ((argument ,op ,index) (make-glil-argument op index)) - ((local ,op ,index) (make-glil-local op index)) - ((external ,op ,depth ,index) (make-glil-external op depth index)) + ((lexical ,local? ,boxed? ,op ,index) (make-glil-lexical local? boxed? op index)) ((toplevel ,op ,name) (make-glil-toplevel op name)) ((module public ,op ,mod ,name) (make-glil-module op mod name #t)) ((module private ,op ,mod ,name) (make-glil-module op mod name #f)) - ((label ,label) (make-label ,label)) + ((label ,label) (make-label label)) ((branch ,inst ,label) (make-glil-branch inst label)) ((call ,inst ,nargs) (make-glil-call inst nargs)) ((mv-call ,nargs ,ra) (make-glil-mv-call nargs ra)) @@ -140,8 +114,8 @@ (define (unparse-glil glil) (record-case glil ;; meta - (( nargs nrest nlocs nexts meta body) - `(program ,nargs ,nrest ,nlocs ,nexts ,meta ,@(map unparse-glil body))) + (( nargs nrest nlocs meta body) + `(program ,nargs ,nrest ,nlocs ,meta ,@(map unparse-glil body))) (( vars) `(bind ,@vars)) (( vars rest) `(mv-bind ,vars ,rest)) (() `(unbind)) @@ -150,12 +124,8 @@ (() `(void)) (( obj) `(const ,obj)) ;; variables - (( op index) - `(argument ,op ,index)) - (( op index) - `(local ,op ,index)) - (( op depth index) - `(external ,op ,depth ,index)) + (( local? boxed? op index) + `(lexical ,local? ,boxed? ,op ,index)) (( op name) `(toplevel ,op ,name)) (( op mod name public?) diff --git a/module/language/glil/compile-assembly.scm b/module/language/glil/compile-assembly.scm index ffac9dbfb..c67ef694b 100644 --- a/module/language/glil/compile-assembly.scm +++ b/module/language/glil/compile-assembly.scm @@ -2,20 +2,19 @@ ;; Copyright (C) 2001, 2009 Free Software Foundation, Inc. -;; 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 2, 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 COPYING. If not, write to -;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Code: @@ -28,6 +27,7 @@ #:use-module ((system vm program) #:select (make-binding)) #:use-module (ice-9 receive) #:use-module ((srfi srfi-1) #:select (fold)) + #:use-module (rnrs bytevector) #:export (compile-assembly)) ;; Variable cache cells go in the object table, and serialize as their @@ -72,27 +72,26 @@ (if (and (null? bindings) (null? sources) (null? tail)) #f (compile-assembly - (make-glil-program 0 0 0 0 '() + (make-glil-program 0 0 0 '() (list (make-glil-const `(,bindings ,sources ,@tail)) (make-glil-call 'return 1)))))) ;; A functional stack of names of live variables. -(define (make-open-binding name ext? index) - (list name ext? index)) +(define (make-open-binding name boxed? index) + (list name boxed? index)) (define (make-closed-binding open-binding start end) (make-binding (car open-binding) (cadr open-binding) (caddr open-binding) start end)) -(define (open-binding bindings vars nargs start) +(define (open-binding bindings vars start) (cons (acons start (map (lambda (v) (pmatch v - ((,name argument ,i) (make-open-binding name #f i)) - ((,name local ,i) (make-open-binding name #f (+ nargs i))) - ((,name external ,i) (make-open-binding name #t i)) - (else (error "unknown binding type" name type)))) + ((,name ,boxed? ,i) + (make-open-binding name boxed? i)) + (else (error "unknown binding type" v)))) vars) (car bindings)) (cdr bindings))) @@ -129,81 +128,88 @@ (define (compile-assembly glil) (receive (code . _) - (glil->assembly glil 0 '() '(()) '() '() #f -1) + (glil->assembly glil #t '(()) '() '() #f -1) (car code))) (define (make-object-table objects) (and (not (null? objects)) (list->vector (cons #f objects)))) -(define (glil->assembly glil nargs nexts-stack bindings +(define (glil->assembly glil toplevel? bindings source-alist label-alist object-alist addr) (define (emit-code x) - (values (map assembly-pack x) bindings source-alist label-alist object-alist)) + (values x bindings source-alist label-alist object-alist)) (define (emit-code/object x object-alist) - (values (map assembly-pack x) bindings source-alist label-alist object-alist)) + (values x bindings source-alist label-alist object-alist)) (record-case glil - (( nargs nrest nlocs nexts meta body closure-level) - (let ((toplevel? (null? nexts-stack))) - (define (process-body) - (let ((nexts-stack (cons nexts nexts-stack))) - (let lp ((body body) (code '()) (bindings '(())) (source-alist '()) - (label-alist '()) (object-alist (if toplevel? #f '())) (addr 0)) - (cond - ((null? body) - (values (reverse code) - (close-all-bindings bindings addr) - (limn-sources (reverse! source-alist)) - (reverse label-alist) - (and object-alist (map car (reverse object-alist))) - addr)) - (else - (receive (subcode bindings source-alist label-alist object-alist) - (glil->assembly (car body) nargs nexts-stack bindings - source-alist label-alist object-alist addr) - (lp (cdr body) (append (reverse subcode) code) - bindings source-alist label-alist object-alist - (addr+ addr subcode)))))))) + (( nargs nrest nlocs meta body) + (define (process-body) + (let lp ((body body) (code '()) (bindings '(())) (source-alist '()) + (label-alist '()) (object-alist (if toplevel? #f '())) (addr 0)) + (cond + ((null? body) + (values (reverse code) + (close-all-bindings bindings addr) + (limn-sources (reverse! source-alist)) + (reverse label-alist) + (and object-alist (map car (reverse object-alist))) + addr)) + (else + (receive (subcode bindings source-alist label-alist object-alist) + (glil->assembly (car body) #f bindings + source-alist label-alist object-alist addr) + (lp (cdr body) (append (reverse subcode) code) + bindings source-alist label-alist object-alist + (addr+ addr subcode))))))) - (receive (code bindings sources labels objects len) - (process-body) - (let ((prog `(load-program ,nargs ,nrest ,nlocs ,nexts ,labels - ,len - ,(make-meta bindings sources meta) - . ,code))) - (cond - (toplevel? - ;; toplevel bytecode isn't loaded by the vm, no way to do - ;; object table or closure capture (not in the bytecode, - ;; anyway) - (emit-code (align-program prog addr))) - (else - (let ((table (dump-object (make-object-table objects) addr)) - (closure (if (> closure-level 0) '((make-closure)) '()))) - (cond - (object-alist - ;; if we are being compiled from something with an object - ;; table, cache the program there - (receive (i object-alist) - (object-index-and-alist (make-subprogram table prog) - object-alist) - (emit-code/object `((object-ref ,i) ,@closure) - object-alist))) - (else - ;; otherwise emit a load directly - (emit-code `(,@table ,@(align-program prog (addr+ addr table)) - ,@closure))))))))))) + (receive (code bindings sources labels objects len) + (process-body) + (let* ((meta (make-meta bindings sources meta)) + (meta-pad (if meta (modulo (- 8 (modulo len 8)) 8) 0)) + (prog `(load-program ,nargs ,nrest ,nlocs ,labels + ,(+ len meta-pad) + ,meta + ,@code + ,@(if meta + (make-list meta-pad '(nop)) + '())))) + (cond + (toplevel? + ;; toplevel bytecode isn't loaded by the vm, no way to do + ;; object table or closure capture (not in the bytecode, + ;; anyway) + (emit-code (align-program prog addr))) + (else + (let ((table (make-object-table objects))) + (cond + (object-alist + ;; if we are being compiled from something with an object + ;; table, cache the program there + (receive (i object-alist) + (object-index-and-alist (make-subprogram table prog) + object-alist) + (emit-code/object `(,(if (< i 256) + `(object-ref ,i) + `(long-object-ref ,(quotient i 256) + ,(modulo i 256)))) + object-alist))) + (else + ;; otherwise emit a load directly + (let ((table-code (dump-object table addr))) + (emit-code + `(,@table-code + ,@(align-program prog (addr+ addr table-code))))))))))))) (( vars) (values '() - (open-binding bindings vars nargs addr) + (open-binding bindings vars addr) source-alist label-alist object-alist)) (( vars rest) (values `((truncate-values ,(length vars) ,(if rest 1 0))) - (open-binding bindings vars nargs addr) + (open-binding bindings vars addr) source-alist label-alist object-alist)) @@ -235,27 +241,57 @@ (else (receive (i object-alist) (object-index-and-alist obj object-alist) - (emit-code/object `((object-ref ,i)) + (emit-code/object (if (< i 256) + `((object-ref ,i)) + `((long-object-ref ,(quotient i 256) + ,(modulo i 256)))) object-alist))))) - (( op index) - (emit-code (if (eq? op 'ref) - `((local-ref ,index)) - `((local-set ,index))))) - - (( op index) - (emit-code (if (eq? op 'ref) - `((local-ref ,(+ nargs index))) - `((local-set ,(+ nargs index)))))) - - (( op depth index) - (emit-code (let lp ((d depth) (n 0) (stack nexts-stack)) - (if (> d 0) - (lp (1- d) (+ n (car stack)) (cdr stack)) - (if (eq? op 'ref) - `((external-ref ,(+ n index))) - `((external-set ,(+ n index)))))))) - + (( local? boxed? op index) + (emit-code + (if local? + (if (< index 256) + (case op + ((ref) (if boxed? + `((local-boxed-ref ,index)) + `((local-ref ,index)))) + ((set) (if boxed? + `((local-boxed-set ,index)) + `((local-set ,index)))) + ((box) `((box ,index))) + ((empty-box) `((empty-box ,index))) + ((fix) `((fix-closure 0 ,index))) + (else (error "what" op))) + (let ((a (quotient i 256)) + (b (modulo i 256))) + `((,(case op + ((ref) + (if boxed? + `((long-local-ref ,a ,b) + (variable-ref)) + `((long-local-ref ,a ,b)))) + ((set) + (if boxed? + `((long-local-ref ,a ,b) + (variable-set)) + `((long-local-set ,a ,b)))) + ((box) + `((make-variable) + (variable-set) + (long-local-set ,a ,b))) + ((empty-box) + `((make-variable) + (long-local-set ,a ,b))) + ((fix) + `((fix-closure ,a ,b))) + (else (error "what" op))) + ,index)))) + `((,(case op + ((ref) (if boxed? 'free-boxed-ref 'free-ref)) + ((set) (if boxed? 'free-boxed-set (error "what." glil))) + (else (error "what" op))) + ,index))))) + (( op name) (case op ((ref set) @@ -270,13 +306,20 @@ (receive (i object-alist) (object-index-and-alist (make-variable-cache-cell name) object-alist) - (emit-code/object (case op - ((ref) `((toplevel-ref ,i))) - ((set) `((toplevel-set ,i)))) + (emit-code/object (if (< i 256) + `((,(case op + ((ref) 'toplevel-ref) + ((set) 'toplevel-set)) + ,i)) + `((,(case op + ((ref) 'long-toplevel-ref) + ((set) 'long-toplevel-set)) + ,(quotient i 256) + ,(modulo i 256)))) object-alist))))) ((define) - (emit-code `((define ,(symbol->string name)) - (variable-set)))) + (emit-code `(,@(dump-object name addr) + (define)))) (else (error "unknown toplevel var kind" op name)))) @@ -303,11 +346,12 @@ (error "unknown module var kind" op key))))) (( label) - (values '() - bindings - source-alist - (acons label addr label-alist) - object-alist)) + (let ((code (align-block addr))) + (values code + bindings + source-alist + (acons label (addr+ addr code) label-alist) + object-alist))) (( inst label) (emit-code `((,inst ,label)))) @@ -318,7 +362,12 @@ (error "Unknown instruction:" inst)) (let ((pops (instruction-pops inst))) (cond ((< pops 0) - (emit-code `((,inst ,nargs)))) + (case (instruction-length inst) + ((1) (emit-code `((,inst ,nargs)))) + ((2) (emit-code `((,inst ,(quotient nargs 256) + ,(modulo nargs 256))))) + (else (error "Unknown length for variable-arg instruction:" + inst (instruction-length inst))))) ((= pops nargs) (emit-code `((,inst)))) (else @@ -335,25 +384,27 @@ ((object->assembly x) => list) ((variable-cache-cell? x) (dump-object (variable-cache-cell-key x) addr)) ((subprogram? x) - `(,@(subprogram-table x) - ,@(align-program (subprogram-prog x) - (addr+ addr (subprogram-table x))))) - ((and (integer? x) (exact? x)) - (let ((str (do ((n x (quotient n 256)) - (l '() (cons (modulo n 256) l))) - ((= n 0) - (list->string (map integer->char l)))))) - (if (< x 0) - `((load-integer ,str)) - `((load-unsigned-integer ,str))))) + (let ((table-code (dump-object (subprogram-table x) addr))) + `(,@table-code + ,@(align-program (subprogram-prog x) + (addr+ addr table-code))))) ((number? x) `((load-number ,(number->string x)))) ((string? x) - `((load-string ,x))) + (case (string-width x) + ((1) `((load-string ,x))) + ((4) (align-code `(load-wide-string ,x) addr 4 4)) + (else (error "bad string width" x)))) ((symbol? x) - `((load-symbol ,(symbol->string x)))) + (let ((str (symbol->string x))) + (case (string-width str) + ((1) `((load-symbol ,str))) + ((4) `(,@(dump-object str addr) + (make-symbol))) + (else (error "bad string width" str))))) ((keyword? x) - `((load-keyword ,(symbol->string (keyword->symbol x))))) + `(,@(dump-object (keyword->symbol x) addr) + (make-keyword))) ((list? x) (let ((tail (let ((len (length x))) (if (>= len 65536) (too-long "list")) @@ -380,6 +431,16 @@ (let ((code (dump-object (vector-ref x i) addr))) (dump-objects (1+ i) (cons code codes) (addr+ addr code))))))) + ((and (array? x) (symbol? (array-type x))) + (let* ((type (dump-object (array-type x) addr)) + (shape (dump-object (array-shape x) (addr+ addr type)))) + `(,@type + ,@shape + ,@(align-code + `(load-array ,(uniform-array->bytevector x)) + (addr+ (addr+ addr type) shape) + 8 + 4)))) (else (error "assemble: unrecognized object" x)))) diff --git a/module/language/glil/decompile-assembly.scm b/module/language/glil/decompile-assembly.scm index a98c39975..3cb887d44 100644 --- a/module/language/glil/decompile-assembly.scm +++ b/module/language/glil/decompile-assembly.scm @@ -1,21 +1,20 @@ ;;; Guile VM code converters -;; Copyright (C) 2001 Free Software Foundation, Inc. +;; Copyright (C) 2001, 2009 Free Software Foundation, Inc. -;; 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 2, 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 COPYING. If not, write to -;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Code: @@ -32,8 +31,8 @@ (define (decompile-toplevel x) (pmatch x - ((load-program ,nargs ,nrest ,nlocs ,nexts ,labels ,len ,meta . ,body) - (decompile-load-program nargs nrest nlocs nexts + ((load-program ,nargs ,nrest ,nlocs ,labels ,len ,meta . ,body) + (decompile-load-program nargs nrest nlocs (decompile-meta meta) body labels #f)) (else @@ -57,7 +56,7 @@ ((glil-program? (car in)) (lp (cdr in) (cons (car in) out))) (else (lp (cdr in) (cons (make-glil-const (car l)) out)))))) -(define (decompile-load-program nargs nrest nlocs nexts meta body labels +(define (decompile-load-program nargs nrest nlocs meta body labels objects) (let ((glil-labels (sort (map (lambda (x) (cons (cdr x) (make-glil-label (car x)))) @@ -101,19 +100,11 @@ (cond ((null? in) (or (null? stack) (error "leftover stack insts" stack body)) - (make-glil-program nargs nrest nlocs nexts props (reverse out) #f)) + (make-glil-program nargs nrest nlocs props (reverse out) #f)) ((pop-bindings! pos) => (lambda (bindings) (lp in stack - (cons (make-glil-bind - (map (lambda (x) - (let ((name (binding:name x)) - (i (binding:index x))) - (cond - ((binding:extp x) `(,name external ,i)) - ((< i nargs) `(,name argument ,i)) - (else `(,name local ,(- i nargs)))))) - bindings)) + (cons (make-glil-bind bindings) out) pos))) ((pop-unbindings! pos) @@ -175,15 +166,11 @@ (1+ pos))) ((local-ref ,n) (lp (cdr in) (cons *placeholder* stack) - (cons (if (< n nargs) - (make-glil-argument 'ref n) - (make-glil-local 'ref (- n nargs))) + (cons (make-glil-local 'ref n) out) (+ pos 2))) ((local-set ,n) (lp (cdr in) (cdr stack) - (cons (if (< n nargs) - (make-glil-argument 'set n) - (make-glil-local 'set (- n nargs))) + (cons (make-glil-local 'set n) (emit-constants (list-head stack 1) out)) (+ pos 2))) ((br-if-not ,l) diff --git a/module/language/glil/spec.scm b/module/language/glil/spec.scm index 3e4e10c6a..d5291a211 100644 --- a/module/language/glil/spec.scm +++ b/module/language/glil/spec.scm @@ -2,20 +2,19 @@ ;; Copyright (C) 2001 Free Software Foundation, Inc. -;; 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 2, 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 COPYING. If not, write to -;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Code: @@ -30,7 +29,7 @@ (apply write (unparse-glil exp) port)) (define (compile-asm x e opts) - (values (compile-assembly x) e)) + (values (compile-assembly x) e e)) (define-language glil #:title "Guile Lowlevel Intermediate Language (GLIL)" diff --git a/module/language/objcode.scm b/module/language/objcode.scm index aea546c66..d8bcda879 100644 --- a/module/language/objcode.scm +++ b/module/language/objcode.scm @@ -2,20 +2,19 @@ ;; Copyright (C) 2001 Free Software Foundation, Inc. -;; 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 2, 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 COPYING. If not, write to -;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Code: diff --git a/module/language/objcode/spec.scm b/module/language/objcode/spec.scm index 9ce8bf5e5..4cb600f1d 100644 --- a/module/language/objcode/spec.scm +++ b/module/language/objcode/spec.scm @@ -1,21 +1,20 @@ ;;; Guile Lowlevel Intermediate Language -;; Copyright (C) 2001 Free Software Foundation, Inc. +;; Copyright (C) 2001, 2009 Free Software Foundation, Inc. -;; 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 2, 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 COPYING. If not, write to -;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Code: @@ -32,7 +31,7 @@ (if env (car env) (current-module))) (define (objcode-env-externals env) - (if env (cdr env) '())) + (and env (vector? (cdr env)) (cdr env))) (define (objcode->value x e opts) (let ((thunk (make-program x #f (objcode-env-externals e)))) @@ -40,8 +39,8 @@ (save-module-excursion (lambda () (set-current-module (objcode-env-module e)) - (values (thunk) #f))) - (values (thunk) #f)))) + (values (thunk) #f e))) + (values (thunk) #f e)))) ;; since locals are allocated on the stack and can have limited scope, ;; in many cases we use one local for more than one lexical variable. so @@ -67,23 +66,16 @@ ((program? x) (let ((objs (program-objects x)) (meta (program-meta x)) - (exts (program-external x)) + (free-vars (program-free-variables x)) (binds (program-bindings x)) (srcs (program-sources x)) (nargs (arity:nargs (program-arity x)))) - (let ((blocs (and binds - (collapse-locals - (append (list-head binds nargs) - (filter (lambda (x) (not (binding:extp x))) - (list-tail binds nargs)))))) - (bexts (and binds - (filter binding:extp binds)))) + (let ((blocs (and binds (collapse-locals binds)))) (values (program-objcode x) `((objects . ,objs) (meta . ,(and meta (meta))) - (exts . ,exts) + (free-vars . ,free-vars) (blocs . ,blocs) - (bexts . ,bexts) (sources . ,srcs)))))) ((objcode? x) (values x #f)) diff --git a/module/language/r5rs/core.il b/module/language/r5rs/core.il index ad40fcc1a..c614a6fe2 100644 --- a/module/language/r5rs/core.il +++ b/module/language/r5rs/core.il @@ -2,20 +2,19 @@ ;; Copyright (C) 2001 Free Software Foundation, Inc. -;; 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 2, 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 COPYING. If not, write to -;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Code: diff --git a/module/language/r5rs/expand.scm b/module/language/r5rs/expand.scm index 45b722717..e8910ae1b 100644 --- a/module/language/r5rs/expand.scm +++ b/module/language/r5rs/expand.scm @@ -2,20 +2,19 @@ ;; Copyright (C) 2001 Free Software Foundation, Inc. -;; 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 2, 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 COPYING. If not, write to -;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Code: diff --git a/module/language/r5rs/null.il b/module/language/r5rs/null.il index efdc5f398..a290025de 100644 --- a/module/language/r5rs/null.il +++ b/module/language/r5rs/null.il @@ -2,19 +2,18 @@ ;; Copyright (C) 2001 Free Software Foundation, Inc. -;; 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 2, 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 COPYING. If not, write to -;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Code: diff --git a/module/language/r5rs/spec.scm b/module/language/r5rs/spec.scm index b5d19e6d4..67f8d74cf 100644 --- a/module/language/r5rs/spec.scm +++ b/module/language/r5rs/spec.scm @@ -2,20 +2,19 @@ ;; Copyright (C) 2001 Free Software Foundation, Inc. -;; 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 2, 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 COPYING. If not, write to -;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Code: diff --git a/module/language/scheme/amatch.scm b/module/language/scheme/amatch.scm deleted file mode 100644 index 4ac973620..000000000 --- a/module/language/scheme/amatch.scm +++ /dev/null @@ -1,37 +0,0 @@ -(define-module (language scheme amatch) - #:use-module (ice-9 syncase) - #:export (amatch apat)) -;; FIXME: shouldn't have to export apat... - -;; This is exactly the same as pmatch except that it unpacks annotations -;; as needed. - -(define-syntax amatch - (syntax-rules (else guard) - ((_ (op arg ...) cs ...) - (let ((v (op arg ...))) - (amatch v cs ...))) - ((_ v) (if #f #f)) - ((_ v (else e0 e ...)) (begin e0 e ...)) - ((_ v (pat (guard g ...) e0 e ...) cs ...) - (let ((fk (lambda () (amatch v cs ...)))) - (apat v pat - (if (and g ...) (begin e0 e ...) (fk)) - (fk)))) - ((_ v (pat e0 e ...) cs ...) - (let ((fk (lambda () (amatch v cs ...)))) - (apat v pat (begin e0 e ...) (fk)))))) - -(define-syntax apat - (syntax-rules (_ quote unquote) - ((_ v _ kt kf) kt) - ((_ v () kt kf) (if (null? v) kt kf)) - ((_ v (quote lit) kt kf) - (if (equal? v (quote lit)) kt kf)) - ((_ v (unquote var) kt kf) (let ((var v)) kt)) - ((_ v (x . y) kt kf) - (if (apair? v) - (let ((vx (acar v)) (vy (acdr v))) - (apat vx x (apat vy y kt kf) kf)) - kf)) - ((_ v lit kt kf) (if (eq? v (quote lit)) kt kf)))) diff --git a/module/language/scheme/compile-ghil.scm b/module/language/scheme/compile-ghil.scm index 587a173fe..dc03af6cf 100644 --- a/module/language/scheme/compile-ghil.scm +++ b/module/language/scheme/compile-ghil.scm @@ -2,20 +2,19 @@ ;; Copyright (C) 2001 Free Software Foundation, Inc. -;; 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 2, 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 COPYING. If not, write to -;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Code: @@ -27,16 +26,15 @@ #:use-module (system vm objcode) #:use-module (ice-9 receive) #:use-module (ice-9 optargs) - #:use-module ((ice-9 syncase) #:select (sc-macro)) + #:use-module (language tree-il) #:use-module ((system base compile) #:select (syntax-error)) #:export (compile-ghil translate-1 *translate-table* define-scheme-translator)) - ;;; environment := #f ;;; | MODULE ;;; | COMPILE-ENV -;;; compile-env := (MODULE LEXICALS . EXTERNALS) +;;; compile-env := (MODULE LEXICALS|GHIL-ENV . EXTERNALS) (define (cenv-module env) (cond ((not env) #f) ((module? env) env) @@ -47,7 +45,9 @@ (cond ((not env) (make-ghil-toplevel-env)) ((module? env) (make-ghil-toplevel-env)) ((pair? env) - (ghil-env-dereify (cadr env))) + (if (struct? (cadr env)) + (cadr env) + (ghil-env-dereify (cadr env)))) (else (error "bad environment" env)))) (define (cenv-externals env) @@ -56,6 +56,8 @@ ((pair? env) (cddr env)) (else (error "bad environment" env)))) +(define (make-cenv module lexicals externals) + (cons module (cons lexicals externals))) @@ -65,11 +67,14 @@ (and=> (cenv-module e) set-current-module) (call-with-ghil-environment (cenv-ghil-env e) '() (lambda (env vars) - (values (make-ghil-lambda env #f vars #f '() (translate-1 env #f x)) - (and e - (cons* (cenv-module e) - (ghil-env-parent env) - (cenv-externals e))))))))) + (let ((x (tree-il->scheme + (sc-expand x 'c '(compile load eval))))) + (let ((x (make-ghil-lambda env #f vars #f '() + (translate-1 env #f x))) + (cenv (make-cenv (current-module) + (ghil-env-parent env) + (if e (cenv-externals e) '())))) + (values x cenv cenv)))))))) ;;; @@ -88,37 +93,26 @@ ;; ;; FIXME shadowing lexicals? (define (lookup-transformer head retrans) + (define (module-ref/safe mod sym) + (and mod + (and=> (module-variable mod sym) + (lambda (var) + ;; unbound vars can happen if the module + ;; definition forward-declared them + (and (variable-bound? var) (variable-ref var)))))) (let* ((mod (current-module)) (val (cond - ((symbol? head) - (and=> (module-variable mod head) - (lambda (var) - ;; unbound vars can happen if the module - ;; definition forward-declared them - (and (variable-bound? var) (variable-ref var))))) - ;; allow macros to be unquoted into the output of a macro - ;; expansion - ((macro? head) head) + ((symbol? head) (module-ref/safe mod head)) + ((pmatch head + ((@ ,modname ,sym) + (module-ref/safe (resolve-interface modname) sym)) + ((@@ ,modname ,sym) + (module-ref/safe (resolve-module modname) sym)) + (else #f))) (else #f)))) (cond ((hashq-ref *translate-table* val)) - ((defmacro? val) - (lambda (env loc exp) - (retrans (apply (defmacro-transformer val) (cdr exp))))) - - ((eq? val sc-macro) - ;; syncase! - (let* ((eec (@@ (ice-9 syncase) expansion-eval-closure)) - (sc-expand3 (@@ (ice-9 syncase) sc-expand3))) - (lambda (env loc exp) - (retrans - (with-fluids ((eec (module-eval-closure mod))) - (sc-expand3 exp 'c '(compile load eval))))))) - - ((primitive-macro? val) - (syntax-error #f "unhandled primitive macro" head)) - ((macro? val) (syntax-error #f "unknown kind of macro" head)) @@ -167,7 +161,7 @@ (define-macro (define-scheme-translator sym . clauses) `(hashq-set! (@ (language scheme compile-ghil) *translate-table*) - ,sym + (module-ref (current-module) ',sym) (lambda (e l exp) (define (retrans x) ((@ (language scheme compile-ghil) translate-1) @@ -419,16 +413,6 @@ (,args (-> (values (map retrans args))))) -(define-scheme-translator compile-time-environment - ;; (compile-time-environment) - ;; => (MODULE LEXICALS . EXTERNALS) - (() - (-> (inline 'cons - (list (retrans '(current-module)) - (-> (inline 'cons - (list (-> (reified-env)) - (-> (inline 'externals '())))))))))) - (define (lookup-apply-transformer proc) (cond ((eq? proc values) (lambda (e l args) diff --git a/module/language/scheme/compile-tree-il.scm b/module/language/scheme/compile-tree-il.scm new file mode 100644 index 000000000..4ac33d77e --- /dev/null +++ b/module/language/scheme/compile-tree-il.scm @@ -0,0 +1,63 @@ +;;; Guile Scheme specification + +;; Copyright (C) 2001 Free Software Foundation, Inc. + +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +;;; Code: + +(define-module (language scheme compile-tree-il) + #:use-module (language tree-il) + #:export (compile-tree-il)) + +;;; environment := #f +;;; | MODULE +;;; | COMPILE-ENV +;;; compile-env := (MODULE LEXICALS . EXTERNALS) +(define (cenv-module env) + (cond ((not env) #f) + ((module? env) env) + ((and (pair? env) (module? (car env))) (car env)) + (else (error "bad environment" env)))) + +(define (cenv-lexicals env) + (cond ((not env) '()) + ((module? env) '()) + ((pair? env) (cadr env)) + (else (error "bad environment" env)))) + +(define (cenv-externals env) + (cond ((not env) '()) + ((module? env) '()) + ((pair? env) (cddr env)) + (else (error "bad environment" env)))) + +(define (make-cenv module lexicals externals) + (cons module (cons lexicals externals))) + +(define (location x) + (and (pair? x) + (let ((props (source-properties x))) + (and (not (null? props)) + props)))) + +(define (compile-tree-il x e opts) + (save-module-excursion + (lambda () + (and=> (cenv-module e) set-current-module) + (let* ((x (sc-expand x 'c '(compile load eval))) + (cenv (make-cenv (current-module) + (cenv-lexicals e) (cenv-externals e)))) + (values x cenv cenv))))) diff --git a/module/language/scheme/decompile-tree-il.scm b/module/language/scheme/decompile-tree-il.scm new file mode 100644 index 000000000..9243f4e6a --- /dev/null +++ b/module/language/scheme/decompile-tree-il.scm @@ -0,0 +1,26 @@ +;;; Guile VM code converters + +;; Copyright (C) 2001,2009 Free Software Foundation, Inc. + +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +;;; Code: + +(define-module (language scheme decompile-tree-il) + #:use-module (language tree-il) + #:export (decompile-tree-il)) + +(define (decompile-tree-il x env opts) + (values (tree-il->scheme x) env)) diff --git a/module/language/scheme/expand.scm b/module/language/scheme/expand.scm deleted file mode 100644 index ee689a092..000000000 --- a/module/language/scheme/expand.scm +++ /dev/null @@ -1,307 +0,0 @@ -;;; Guile Scheme specification - -;; Copyright (C) 2001 Free Software Foundation, Inc. - -;; 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 2, 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 COPYING. If not, write to -;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Code: - -(define-module (language scheme expand) - #:use-module (language scheme amatch) - #:use-module (ice-9 annotate) - #:use-module (ice-9 optargs) - #:use-module ((ice-9 syncase) #:select (sc-macro)) - #:use-module ((system base compile) #:select (syntax-error)) - #:export (expand *expand-table* define-scheme-expander)) - -(define (aref x) (if (annotation? x) (annotation-expression x) x)) -(define (apair? x) (pair? (aref x))) -(define (acar x) (car (aref x))) -(define (acdr x) (cdr (aref x))) -(define (acaar x) (acar (acar x))) -(define (acdar x) (acdr (acar x))) -(define (acadr x) (acar (acdr x))) -(define (acddr x) (acdr (acdr x))) -(define (aloc x) (and (annotation? x) (annotation-source x))) -(define (re-annotate x y) - (if (annotation? x) - (make-annotation y (annotation-source x)) - y)) -(define-macro (-> exp) `(re-annotate x ,exp)) - -(define* (expand x #:optional (mod (current-module)) (once? #f)) - (define re-expand - (if once? - (lambda (x) x) - (lambda (x) (expand x mod once?)))) - (let ((exp (if (annotation? x) (annotation-expression x) x))) - (cond - ((pair? exp) - (let ((head (car exp)) (tail (cdr exp))) - (cond - ;; allow macros to be unquoted into the output of a macro - ;; expansion - ((or (symbol? head) (macro? head)) - (let ((val (cond - ((macro? head) head) - ((module-variable mod head) - => (lambda (var) - ;; unbound vars can happen if the module - ;; definition forward-declared them - (and (variable-bound? var) (variable-ref var)))) - (else #f)))) - (cond - ((hashq-ref *expand-table* val) - => (lambda (expand1) (expand1 x re-expand))) - - ((defmacro? val) - (re-expand (-> (apply (defmacro-transformer val) - (deannotate tail))))) - - ((eq? val sc-macro) - ;; syncase! - (let* ((eec (@@ (ice-9 syncase) expansion-eval-closure)) - (sc-expand3 (@@ (ice-9 syncase) sc-expand3))) - (re-expand - (with-fluids ((eec (module-eval-closure mod))) - ;; fixme - (sc-expand3 (deannotate exp) 'c '(compile load eval)))))) - - ((primitive-macro? val) - (syntax-error (aloc x) "unhandled primitive macro" head)) - - ((macro? val) - (syntax-error (aloc x) "unknown kind of macro" head)) - - (else - (-> (cons head (map re-expand tail))))))) - - (else - (-> (map re-expand exp)))))) - - (else x)))) - - -(define *expand-table* (make-hash-table)) - -(define-macro (define-scheme-expander sym . clauses) - `(hashq-set! (@ (language scheme expand) *expand-table*) - ,sym - (lambda (x re-expand) - (define syntax-error (@ (system base compile) syntax-error)) - (amatch (acdr x) - ,@clauses - ,@(if (assq 'else clauses) '() - `((else - (syntax-error (aloc x) (format #f "bad ~A" ',sym) x)))))))) - -(define-scheme-expander quote - ;; (quote OBJ) - ((,obj) x)) - -(define-scheme-expander quasiquote - ;; (quasiquote OBJ) - ((,obj) - (-> `(,'quasiquote - ,(let lp ((x obj) (level 0)) - (cond ((not (apair? x)) x) - ;; FIXME: hygiene regarding imported , / ,@ rebinding - ((memq (acar x) '(unquote unquote-splicing)) - (amatch (acdr x) - ((,obj) - (cond - ((zero? level) - (-> `(,(acar x) ,(re-expand obj)))) - (else - (-> `(,(acar x) ,(lp obj (1- level))))))) - (else (syntax-error (aloc x) (format #f "bad ~A" (acar x)) x)))) - ((eq? (acar x) 'quasiquote) - (amatch (acdr x) - ((,obj) (-> `(,'quasiquote ,(lp obj (1+ level))))) - (else (syntax-error (aloc x) "bad quasiquote" x)))) - (else (-> (cons (lp (acar x) level) (lp (acdr x) level)))))))))) - -(define-scheme-expander define - ;; (define NAME VAL) - ((,name ,val) (guard (symbol? name)) - (-> `(define ,name ,(re-expand val)))) - ;; (define (NAME FORMALS...) BODY...) - (((,name . ,formals) . ,body) (guard (symbol? name)) - ;; -> (define NAME (lambda FORMALS BODY...)) - (re-expand (-> `(define ,name (lambda ,formals . ,body)))))) - -(define-scheme-expander set! - ;; (set! (NAME ARGS...) VAL) - (((,name . ,args) ,val) (guard (symbol? name) - (not (eq? name '@)) (not (eq? name '@@))) - ;; -> ((setter NAME) ARGS... VAL) - (re-expand (-> `((setter ,name) ,@args ,val)))) - - ;; (set! NAME VAL) - ((,name ,val) (guard (symbol? name)) - (-> `(set! ,name ,(re-expand val))))) - -(define-scheme-expander if - ;; (if TEST THEN [ELSE]) - ((,test ,then) - (-> `(if ,(re-expand test) ,(re-expand then)))) - ((,test ,then ,else) - (-> `(if ,(re-expand test) ,(re-expand then) ,(re-expand else))))) - -(define-scheme-expander and - ;; (and EXPS...) - (,tail - (-> `(and . ,(map re-expand tail))))) - -(define-scheme-expander or - ;; (or EXPS...) - (,tail - (-> `(or . ,(map re-expand tail))))) - -(define-scheme-expander begin - ;; (begin EXPS...) - ((,single-exp) - (-> (re-expand single-exp))) - (,tail - (-> `(begin . ,(map re-expand tail))))) - -(define (valid-bindings? bindings . it-is-for-do) - (define (valid-binding? b) - (amatch b - ((,sym ,var) (guard (symbol? sym)) #t) - ((,sym ,var ,update) (guard (pair? it-is-for-do) (symbol? sym)) #t) - (else #f))) - (and (list? (aref bindings)) - (and-map valid-binding? (aref bindings)))) - -(define-scheme-expander let - ;; (let NAME ((SYM VAL) ...) BODY...) - ((,name ,bindings . ,body) (guard (symbol? name) - (valid-bindings? bindings)) - ;; -> (letrec ((NAME (lambda (SYM...) BODY...))) (NAME VAL...)) - (re-expand (-> `(letrec ((,name (lambda ,(map acar (aref bindings)) - . ,body))) - (,name . ,(map acadr (aref bindings))))))) - - ((() . ,body) - (re-expand (expand-internal-defines body))) - - ;; (let ((SYM VAL) ...) BODY...) - ((,bindings . ,body) (guard (valid-bindings? bindings)) - (-> `(let ,(map (lambda (x) - ;; nb, relies on -> non-hygiene - (-> `(,(acar x) ,(re-expand (acadr x))))) - (aref bindings)) - ,(expand-internal-defines (map re-expand body)))))) - -(define-scheme-expander let* - ;; (let* ((SYM VAL) ...) BODY...) - ((() . ,body) - (re-expand (-> `(let () . ,body)))) - ((((,sym ,val) . ,rest) . ,body) (guard (symbol? sym)) - (re-expand (-> `(let ((,sym ,val)) (let* ,rest . ,body)))))) - -(define-scheme-expander letrec - ;; (letrec ((SYM VAL) ...) BODY...) - ((,bindings . ,body) (guard (valid-bindings? bindings)) - (-> `(letrec ,(map (lambda (x) - ;; nb, relies on -> non-hygiene - (-> `(,(acar x) ,(re-expand (acadr x))))) - (aref bindings)) - ,(expand-internal-defines (map re-expand body)))))) - -(define-scheme-expander cond - ;; (cond (CLAUSE BODY...) ...) - (() (-> '(begin))) - (((else . ,body)) (re-expand (-> `(begin ,@body)))) - (((,test) . ,rest) (re-expand (-> `(or ,test (cond ,@rest))))) - (((,test => ,proc) . ,rest) - ;; FIXME hygiene! - (re-expand (-> `(let ((_t ,test)) (if _t (,proc _t) (cond ,@rest)))))) - (((,test . ,body) . ,rest) - (re-expand (-> `(if ,test (begin ,@body) (cond ,@rest)))))) - -(define-scheme-expander case - ;; (case EXP ((KEY...) BODY...) ...) - ((,exp . ,clauses) - ;; FIXME hygiene! - (re-expand - (->`(let ((_t ,exp)) - ,(let loop ((ls clauses)) - (cond ((null? ls) '(begin)) - ((eq? (acaar ls) 'else) `(begin ,@(acdar ls))) - (else `(if (memv _t ',(acaar ls)) - (begin ,@(acdar ls)) - ,(loop (acdr ls))))))))))) - -(define-scheme-expander do - ;; (do ((SYM VAL [UPDATE]) ...) (TEST RESULT...) BODY...) - ((,bindings (,test . ,result) . ,body) (guard (valid-bindings? bindings #t)) - (let ((sym (map acar (aref bindings))) - (val (map acadr (aref bindings))) - (update (map acddr (aref bindings)))) - (define (next s x) (if (pair? x) (car x) s)) - (re-expand - ;; FIXME hygiene! - (-> `(letrec ((_l (lambda ,sym - (if ,test - (begin ,@result) - (begin ,@body - (_l ,@(map next sym update))))))) - (_l ,@val))))))) - -(define-scheme-expander lambda - ;; (lambda FORMALS BODY...) - ((,formals ,docstring ,body1 . ,body) (guard (string? docstring)) - (-> `(lambda ,formals ,docstring ,(expand-internal-defines - (map re-expand (cons body1 body)))))) - ((,formals . ,body) - (-> `(lambda ,formals ,(expand-internal-defines (map re-expand body)))))) - -(define-scheme-expander delay - ;; FIXME not hygienic - ((,expr) - (re-expand `(make-promise (lambda () ,expr))))) - -(define-scheme-expander @ - ((,modname ,sym) - x)) - -(define-scheme-expander @@ - ((,modname ,sym) - x)) - -(define-scheme-expander eval-when - ((,when . ,body) (guard (list? when) (and-map symbol? when)) - (if (memq 'compile when) - (primitive-eval `(begin . ,body))) - (if (memq 'load when) - (-> `(begin . ,body)) - (-> `(begin))))) - -;;; Hum, I don't think this takes imported modifications to `define' -;;; properly into account. (Lexical bindings are OK because of alpha -;;; renaming.) -(define (expand-internal-defines body) - (let loop ((ls body) (ds '())) - (amatch ls - (() (syntax-error l "bad body" body)) - (((define ,name ,val) . _) - (loop (acdr ls) (cons (list name val) ds))) - (else - (if (null? ds) - (if (null? (cdr ls)) (car ls) `(begin ,@ls)) - `(letrec ,ds ,(if (null? (cdr ls)) (car ls) `(begin ,@ls)))))))) diff --git a/module/language/scheme/inline.scm b/module/language/scheme/inline.scm index 462fe7f2f..b178b2adc 100644 --- a/module/language/scheme/inline.scm +++ b/module/language/scheme/inline.scm @@ -2,20 +2,19 @@ ;; Copyright (C) 2001 Free Software Foundation, Inc. -;; 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 2, 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 COPYING. If not, write to -;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Code: diff --git a/module/language/scheme/spec.scm b/module/language/scheme/spec.scm index 8f958eb63..df618581f 100644 --- a/module/language/scheme/spec.scm +++ b/module/language/scheme/spec.scm @@ -1,27 +1,27 @@ ;;; Guile Scheme specification -;; Copyright (C) 2001 Free Software Foundation, Inc. +;; Copyright (C) 2001, 2009 Free Software Foundation, Inc. -;; 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 2, 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 COPYING. If not, write to -;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Code: (define-module (language scheme spec) #:use-module (system base language) - #:use-module (language scheme compile-ghil) + #:use-module (language scheme compile-tree-il) + #:use-module (language scheme decompile-tree-il) #:export (scheme)) ;;; @@ -30,12 +30,6 @@ (read-enable 'positions) -(define (read-file port) - (do ((x (read port) (read port)) - (l '() (cons x l))) - ((eof-object? x) - (cons 'begin (reverse! l))))) - ;;; ;;; Language definition ;;; @@ -44,8 +38,8 @@ #:title "Guile Scheme" #:version "0.5" #:reader read - #:read-file read-file - #:compilers `((ghil . ,compile-ghil)) + #:compilers `((tree-il . ,compile-tree-il)) + #:decompilers `((tree-il . ,decompile-tree-il)) #:evaluator (lambda (x module) (primitive-eval x)) #:printer write ) diff --git a/module/language/tree-il.scm b/module/language/tree-il.scm new file mode 100644 index 000000000..ad8b73176 --- /dev/null +++ b/module/language/tree-il.scm @@ -0,0 +1,474 @@ +;;;; Copyright (C) 2009 Free Software Foundation, Inc. +;;;; +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;;;; + + +(define-module (language tree-il) + #:use-module (srfi srfi-1) + #:use-module (srfi srfi-11) + #:use-module (system base pmatch) + #:use-module (system base syntax) + #:export (tree-il-src + + void? make-void void-src + const? make-const const-src const-exp + primitive-ref? make-primitive-ref primitive-ref-src primitive-ref-name + lexical-ref? make-lexical-ref lexical-ref-src lexical-ref-name lexical-ref-gensym + lexical-set? make-lexical-set lexical-set-src lexical-set-name lexical-set-gensym lexical-set-exp + module-ref? make-module-ref module-ref-src module-ref-mod module-ref-name module-ref-public? + module-set? make-module-set module-set-src module-set-mod module-set-name module-set-public? module-set-exp + toplevel-ref? make-toplevel-ref toplevel-ref-src toplevel-ref-name + toplevel-set? make-toplevel-set toplevel-set-src toplevel-set-name toplevel-set-exp + toplevel-define? make-toplevel-define toplevel-define-src toplevel-define-name toplevel-define-exp + conditional? make-conditional conditional-src conditional-test conditional-then conditional-else + application? make-application application-src application-proc application-args + sequence? make-sequence sequence-src sequence-exps + lambda? make-lambda lambda-src lambda-names lambda-vars lambda-meta lambda-body + let? make-let let-src let-names let-vars let-vals let-body + letrec? make-letrec letrec-src letrec-names letrec-vars letrec-vals letrec-body + fix? make-fix fix-src fix-names fix-vars fix-vals fix-body + let-values? make-let-values let-values-src let-values-names let-values-vars let-values-exp let-values-body + + parse-tree-il + unparse-tree-il + tree-il->scheme + + tree-il-fold + make-tree-il-folder + post-order! + pre-order!)) + +(define-type ( #:common-slots (src)) + () + ( exp) + ( name) + ( name gensym) + ( name gensym exp) + ( mod name public?) + ( mod name public? exp) + ( name) + ( name exp) + ( name exp) + ( test then else) + ( proc args) + ( exps) + ( names vars meta body) + ( names vars vals body) + ( names vars vals body) + ( names vars vals body) + ( names vars exp body)) + + + +(define (location x) + (and (pair? x) + (let ((props (source-properties x))) + (and (pair? props) props)))) + +(define (parse-tree-il exp) + (let ((loc (location exp)) + (retrans (lambda (x) (parse-tree-il x)))) + (pmatch exp + ((void) + (make-void loc)) + + ((apply ,proc . ,args) + (make-application loc (retrans proc) (map retrans args))) + + ((if ,test ,then ,else) + (make-conditional loc (retrans test) (retrans then) (retrans else))) + + ((primitive ,name) (guard (symbol? name)) + (make-primitive-ref loc name)) + + ((lexical ,name) (guard (symbol? name)) + (make-lexical-ref loc name name)) + + ((lexical ,name ,sym) (guard (symbol? name) (symbol? sym)) + (make-lexical-ref loc name sym)) + + ((set! (lexical ,name) ,exp) (guard (symbol? name)) + (make-lexical-set loc name name (retrans exp))) + + ((set! (lexical ,name ,sym) ,exp) (guard (symbol? name) (symbol? sym)) + (make-lexical-set loc name sym (retrans exp))) + + ((@ ,mod ,name) (guard (and-map symbol? mod) (symbol? name)) + (make-module-ref loc mod name #t)) + + ((set! (@ ,mod ,name) ,exp) (guard (and-map symbol? mod) (symbol? name)) + (make-module-set loc mod name #t (retrans exp))) + + ((@@ ,mod ,name) (guard (and-map symbol? mod) (symbol? name)) + (make-module-ref loc mod name #f)) + + ((set! (@@ ,mod ,name) ,exp) (guard (and-map symbol? mod) (symbol? name)) + (make-module-set loc mod name #f (retrans exp))) + + ((toplevel ,name) (guard (symbol? name)) + (make-toplevel-ref loc name)) + + ((set! (toplevel ,name) ,exp) (guard (symbol? name)) + (make-toplevel-set loc name (retrans exp))) + + ((define ,name ,exp) (guard (symbol? name)) + (make-toplevel-define loc name (retrans exp))) + + ((lambda ,names ,vars ,exp) + (make-lambda loc names vars '() (retrans exp))) + + ((lambda ,names ,vars ,meta ,exp) + (make-lambda loc names vars meta (retrans exp))) + + ((const ,exp) + (make-const loc exp)) + + ((begin . ,exps) + (make-sequence loc (map retrans exps))) + + ((let ,names ,vars ,vals ,body) + (make-let loc names vars (map retrans vals) (retrans body))) + + ((letrec ,names ,vars ,vals ,body) + (make-letrec loc names vars (map retrans vals) (retrans body))) + + ((fix ,names ,vars ,vals ,body) + (make-fix loc names vars (map retrans vals) (retrans body))) + + ((let-values ,names ,vars ,exp ,body) + (make-let-values loc names vars (retrans exp) (retrans body))) + + (else + (error "unrecognized tree-il" exp))))) + +(define (unparse-tree-il tree-il) + (record-case tree-il + (() + '(void)) + + (( proc args) + `(apply ,(unparse-tree-il proc) ,@(map unparse-tree-il args))) + + (( test then else) + `(if ,(unparse-tree-il test) ,(unparse-tree-il then) ,(unparse-tree-il else))) + + (( name) + `(primitive ,name)) + + (( name gensym) + `(lexical ,name ,gensym)) + + (( name gensym exp) + `(set! (lexical ,name ,gensym) ,(unparse-tree-il exp))) + + (( mod name public?) + `(,(if public? '@ '@@) ,mod ,name)) + + (( mod name public? exp) + `(set! (,(if public? '@ '@@) ,mod ,name) ,(unparse-tree-il exp))) + + (( name) + `(toplevel ,name)) + + (( name exp) + `(set! (toplevel ,name) ,(unparse-tree-il exp))) + + (( name exp) + `(define ,name ,(unparse-tree-il exp))) + + (( names vars meta body) + `(lambda ,names ,vars ,meta ,(unparse-tree-il body))) + + (( exp) + `(const ,exp)) + + (( exps) + `(begin ,@(map unparse-tree-il exps))) + + (( names vars vals body) + `(let ,names ,vars ,(map unparse-tree-il vals) ,(unparse-tree-il body))) + + (( names vars vals body) + `(letrec ,names ,vars ,(map unparse-tree-il vals) ,(unparse-tree-il body))) + + (( names vars vals body) + `(fix ,names ,vars ,(map unparse-tree-il vals) ,(unparse-tree-il body))) + + (( names vars exp body) + `(let-values ,names ,vars ,(unparse-tree-il exp) ,(unparse-tree-il body))))) + +(define (tree-il->scheme e) + (record-case e + (() + '(if #f #f)) + + (( proc args) + `(,(tree-il->scheme proc) ,@(map tree-il->scheme args))) + + (( test then else) + (if (void? else) + `(if ,(tree-il->scheme test) ,(tree-il->scheme then)) + `(if ,(tree-il->scheme test) ,(tree-il->scheme then) ,(tree-il->scheme else)))) + + (( name) + name) + + (( name gensym) + gensym) + + (( name gensym exp) + `(set! ,gensym ,(tree-il->scheme exp))) + + (( mod name public?) + `(,(if public? '@ '@@) ,mod ,name)) + + (( mod name public? exp) + `(set! (,(if public? '@ '@@) ,mod ,name) ,(tree-il->scheme exp))) + + (( name) + name) + + (( name exp) + `(set! ,name ,(tree-il->scheme exp))) + + (( name exp) + `(define ,name ,(tree-il->scheme exp))) + + (( vars meta body) + `(lambda ,vars + ,@(cond ((assq-ref meta 'documentation) => list) (else '())) + ,(tree-il->scheme body))) + + (( exp) + (if (and (self-evaluating? exp) (not (vector? exp))) + exp + (list 'quote exp))) + + (( exps) + `(begin ,@(map tree-il->scheme exps))) + + (( vars vals body) + `(let ,(map list vars (map tree-il->scheme vals)) ,(tree-il->scheme body))) + + (( vars vals body) + `(letrec ,(map list vars (map tree-il->scheme vals)) ,(tree-il->scheme body))) + + (( vars vals body) + ;; not a typo, we really do translate back to letrec + `(letrec ,(map list vars (map tree-il->scheme vals)) ,(tree-il->scheme body))) + + (( vars exp body) + `(call-with-values (lambda () ,(tree-il->scheme exp)) + (lambda ,vars ,(tree-il->scheme body)))))) + + +(define (tree-il-fold leaf down up seed tree) + "Traverse TREE, calling LEAF on each leaf encountered, DOWN upon descent +into a sub-tree, and UP when leaving a sub-tree. Each of these procedures is +invoked as `(PROC TREE SEED)', where TREE is the sub-tree or leaf considered +and SEED is the current result, intially seeded with SEED. + +This is an implementation of `foldts' as described by Andy Wingo in +``Applications of fold to XML transformation''." + (let loop ((tree tree) + (result seed)) + (if (or (null? tree) (pair? tree)) + (fold loop result tree) + (record-case tree + (( exp) + (up tree (loop exp (down tree result)))) + (( exp) + (up tree (loop exp (down tree result)))) + (( exp) + (up tree (loop exp (down tree result)))) + (( exp) + (up tree (loop exp (down tree result)))) + (( test then else) + (up tree (loop else + (loop then + (loop test (down tree result)))))) + (( proc args) + (up tree (loop (cons proc args) (down tree result)))) + (( exps) + (up tree (loop exps (down tree result)))) + (( body) + (up tree (loop body (down tree result)))) + (( vals body) + (up tree (loop body + (loop vals + (down tree result))))) + (( vals body) + (up tree (loop body + (loop vals + (down tree result))))) + (( vals body) + (up tree (loop body + (loop vals + (down tree result))))) + (( exp body) + (up tree (loop body (loop exp (down tree result))))) + (else + (leaf tree result)))))) + + +(define-syntax make-tree-il-folder + (syntax-rules () + ((_ seed ...) + (lambda (tree down up seed ...) + (define (fold-values proc exps seed ...) + (if (null? exps) + (values seed ...) + (let-values (((seed ...) (proc (car exps) seed ...))) + (fold-values proc (cdr exps) seed ...)))) + (let foldts ((tree tree) (seed seed) ...) + (let*-values + (((seed ...) (down tree seed ...)) + ((seed ...) + (record-case tree + (( exp) + (foldts exp seed ...)) + (( exp) + (foldts exp seed ...)) + (( exp) + (foldts exp seed ...)) + (( exp) + (foldts exp seed ...)) + (( test then else) + (let*-values (((seed ...) (foldts test seed ...)) + ((seed ...) (foldts then seed ...))) + (foldts else seed ...))) + (( proc args) + (let-values (((seed ...) (foldts proc seed ...))) + (fold-values foldts args seed ...))) + (( exps) + (fold-values foldts exps seed ...)) + (( body) + (foldts body seed ...)) + (( vals body) + (let*-values (((seed ...) (fold-values foldts vals seed ...))) + (foldts body seed ...))) + (( vals body) + (let*-values (((seed ...) (fold-values foldts vals seed ...))) + (foldts body seed ...))) + (( vals body) + (let*-values (((seed ...) (fold-values foldts vals seed ...))) + (foldts body seed ...))) + (( exp body) + (let*-values (((seed ...) (foldts exp seed ...))) + (foldts body seed ...))) + (else + (values seed ...))))) + (up tree seed ...))))))) + +(define (post-order! f x) + (let lp ((x x)) + (record-case x + (( proc args) + (set! (application-proc x) (lp proc)) + (set! (application-args x) (map lp args))) + + (( test then else) + (set! (conditional-test x) (lp test)) + (set! (conditional-then x) (lp then)) + (set! (conditional-else x) (lp else))) + + (( name gensym exp) + (set! (lexical-set-exp x) (lp exp))) + + (( mod name public? exp) + (set! (module-set-exp x) (lp exp))) + + (( name exp) + (set! (toplevel-set-exp x) (lp exp))) + + (( name exp) + (set! (toplevel-define-exp x) (lp exp))) + + (( vars meta body) + (set! (lambda-body x) (lp body))) + + (( exps) + (set! (sequence-exps x) (map lp exps))) + + (( vars vals body) + (set! (let-vals x) (map lp vals)) + (set! (let-body x) (lp body))) + + (( vars vals body) + (set! (letrec-vals x) (map lp vals)) + (set! (letrec-body x) (lp body))) + + (( vars vals body) + (set! (fix-vals x) (map lp vals)) + (set! (fix-body x) (lp body))) + + (( vars exp body) + (set! (let-values-exp x) (lp exp)) + (set! (let-values-body x) (lp body))) + + (else #f)) + + (or (f x) x))) + +(define (pre-order! f x) + (let lp ((x x)) + (let ((x (or (f x) x))) + (record-case x + (( proc args) + (set! (application-proc x) (lp proc)) + (set! (application-args x) (map lp args))) + + (( test then else) + (set! (conditional-test x) (lp test)) + (set! (conditional-then x) (lp then)) + (set! (conditional-else x) (lp else))) + + (( name gensym exp) + (set! (lexical-set-exp x) (lp exp))) + + (( mod name public? exp) + (set! (module-set-exp x) (lp exp))) + + (( name exp) + (set! (toplevel-set-exp x) (lp exp))) + + (( name exp) + (set! (toplevel-define-exp x) (lp exp))) + + (( vars meta body) + (set! (lambda-body x) (lp body))) + + (( exps) + (set! (sequence-exps x) (map lp exps))) + + (( vars vals body) + (set! (let-vals x) (map lp vals)) + (set! (let-body x) (lp body))) + + (( vars vals body) + (set! (letrec-vals x) (map lp vals)) + (set! (letrec-body x) (lp body))) + + (( vars vals body) + (set! (fix-vals x) (map lp vals)) + (set! (fix-body x) (lp body))) + + (( vars exp body) + (set! (let-values-exp x) (lp exp)) + (set! (let-values-body x) (lp body))) + + (else #f)) + x))) diff --git a/module/language/tree-il/analyze.scm b/module/language/tree-il/analyze.scm new file mode 100644 index 000000000..b93a0bd7e --- /dev/null +++ b/module/language/tree-il/analyze.scm @@ -0,0 +1,617 @@ +;;; TREE-IL -> GLIL compiler + +;; Copyright (C) 2001,2008,2009 Free Software Foundation, Inc. + +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +;;; Code: + +(define-module (language tree-il analyze) + #:use-module (srfi srfi-1) + #:use-module (srfi srfi-9) + #:use-module (system base syntax) + #:use-module (system base message) + #:use-module (language tree-il) + #:export (analyze-lexicals + report-unused-variables)) + +;; Allocation is the process of assigning storage locations for lexical +;; variables. A lexical variable has a distinct "address", or storage +;; location, for each procedure in which it is referenced. +;; +;; A variable is "local", i.e., allocated on the stack, if it is +;; referenced from within the procedure that defined it. Otherwise it is +;; a "closure" variable. For example: +;; +;; (lambda (a) a) ; a will be local +;; `a' is local to the procedure. +;; +;; (lambda (a) (lambda () a)) +;; `a' is local to the outer procedure, but a closure variable with +;; respect to the inner procedure. +;; +;; If a variable is ever assigned, it needs to be heap-allocated +;; ("boxed"). This is so that closures and continuations capture the +;; variable's identity, not just one of the values it may have over the +;; course of program execution. If the variable is never assigned, there +;; is no distinction between value and identity, so closing over its +;; identity (whether through closures or continuations) can make a copy +;; of its value instead. +;; +;; Local variables are stored on the stack within a procedure's call +;; frame. Their index into the stack is determined from their linear +;; postion within a procedure's binding path: +;; (let (0 1) +;; (let (2 3) ...) +;; (let (2) ...)) +;; (let (2 3 4) ...)) +;; etc. +;; +;; This algorithm has the problem that variables are only allocated +;; indices at the end of the binding path. If variables bound early in +;; the path are not used in later portions of the path, their indices +;; will not be recycled. This problem is particularly egregious in the +;; expansion of `or': +;; +;; (or x y z) +;; -> (let ((a x)) (if a a (let ((b y)) (if b b z)))) +;; +;; As you can see, the `a' binding is only used in the ephemeral `then' +;; clause of the first `if', but its index would be reserved for the +;; whole of the `or' expansion. So we have a hack for this specific +;; case. A proper solution would be some sort of liveness analysis, and +;; not our linear allocation algorithm. +;; +;; Closure variables are captured when a closure is created, and stored +;; in a vector. Each closure variable has a unique index into that +;; vector. +;; +;; There is one more complication. Procedures bound by may, in +;; some cases, be rendered inline to their parent procedure. That is to +;; say, +;; +;; (letrec ((lp (lambda () (lp)))) (lp)) +;; => (fix ((lp (lambda () (lp)))) (lp)) +;; => goto FIX-BODY; LP: goto LP; FIX-BODY: goto LP; +;; ^ jump over the loop ^ the fixpoint lp ^ starting off the loop +;; +;; The upshot is that we don't have to allocate any space for the `lp' +;; closure at all, as it can be rendered inline as a loop. So there is +;; another kind of allocation, "label allocation", in which the +;; procedure is simply a label, placed at the start of the lambda body. +;; The label is the gensym under which the lambda expression is bound. +;; +;; The analyzer checks to see that the label is called with the correct +;; number of arguments. Calls to labels compile to rename + goto. +;; Lambda, the ultimate goto! +;; +;; +;; The return value of `analyze-lexicals' is a hash table, the +;; "allocation". +;; +;; The allocation maps gensyms -- recall that each lexically bound +;; variable has a unique gensym -- to storage locations ("addresses"). +;; Since one gensym may have many storage locations, if it is referenced +;; in many procedures, it is a two-level map. +;; +;; The allocation also stored information on how many local variables +;; need to be allocated for each procedure, lexicals that have been +;; translated into labels, and information on what free variables to +;; capture from its lexical parent procedure. +;; +;; That is: +;; +;; sym -> {lambda -> address} +;; lambda -> (nlocs labels . free-locs) +;; +;; address ::= (local? boxed? . index) +;; labels ::= ((sym . lambda-vars) ...) +;; free-locs ::= ((sym0 . address0) (sym1 . address1) ...) +;; free variable addresses are relative to parent proc. + +(define (make-hashq k v) + (let ((res (make-hash-table))) + (hashq-set! res k v) + res)) + +(define (analyze-lexicals x) + ;; bound-vars: lambda -> (sym ...) + ;; all identifiers bound within a lambda + (define bound-vars (make-hash-table)) + ;; free-vars: lambda -> (sym ...) + ;; all identifiers referenced in a lambda, but not bound + ;; NB, this includes identifiers referenced by contained lambdas + (define free-vars (make-hash-table)) + ;; assigned: sym -> #t + ;; variables that are assigned + (define assigned (make-hash-table)) + ;; refcounts: sym -> count + ;; allows us to detect the or-expansion in O(1) time + (define refcounts (make-hash-table)) + ;; labels: sym -> lambda-vars + ;; for determining if fixed-point procedures can be rendered as + ;; labels. lambda-vars may be an improper list. + (define labels (make-hash-table)) + + ;; returns variables referenced in expr + (define (analyze! x proc labels-in-proc tail? tail-call-args) + (define (step y) (analyze! y proc labels-in-proc #f #f)) + (define (step-tail y) (analyze! y proc labels-in-proc tail? #f)) + (define (step-tail-call y args) (analyze! y proc labels-in-proc #f + (and tail? args))) + (define (recur/labels x new-proc labels) + (analyze! x new-proc (append labels labels-in-proc) #t #f)) + (define (recur x new-proc) (analyze! x new-proc '() tail? #f)) + (record-case x + (( proc args) + (apply lset-union eq? (step-tail-call proc args) + (map step args))) + + (( test then else) + (lset-union eq? (step test) (step-tail then) (step-tail else))) + + (( name gensym) + (hashq-set! refcounts gensym (1+ (hashq-ref refcounts gensym 0))) + (if (not (and tail-call-args + (memq gensym labels-in-proc) + (let ((args (hashq-ref labels gensym))) + (and (list? args) + (= (length args) (length tail-call-args)))))) + (hashq-set! labels gensym #f)) + (list gensym)) + + (( name gensym exp) + (hashq-set! assigned gensym #t) + (hashq-set! labels gensym #f) + (lset-adjoin eq? (step exp) gensym)) + + (( mod name public? exp) + (step exp)) + + (( name exp) + (step exp)) + + (( name exp) + (step exp)) + + (( exps) + (let lp ((exps exps) (ret '())) + (cond ((null? exps) '()) + ((null? (cdr exps)) + (lset-union eq? ret (step-tail (car exps)))) + (else + (lp (cdr exps) (lset-union eq? ret (step (car exps)))))))) + + (( vars meta body) + (let ((locally-bound (let rev* ((vars vars) (out '())) + (cond ((null? vars) out) + ((pair? vars) (rev* (cdr vars) + (cons (car vars) out))) + (else (cons vars out)))))) + (hashq-set! bound-vars x locally-bound) + (let* ((referenced (recur body x)) + (free (lset-difference eq? referenced locally-bound)) + (all-bound (reverse! (hashq-ref bound-vars x)))) + (hashq-set! bound-vars x all-bound) + (hashq-set! free-vars x free) + free))) + + (( vars vals body) + (hashq-set! bound-vars proc + (append (reverse vars) (hashq-ref bound-vars proc))) + (lset-difference eq? + (apply lset-union eq? (step-tail body) (map step vals)) + vars)) + + (( vars vals body) + (hashq-set! bound-vars proc + (append (reverse vars) (hashq-ref bound-vars proc))) + (for-each (lambda (sym) (hashq-set! assigned sym #t)) vars) + (lset-difference eq? + (apply lset-union eq? (step-tail body) (map step vals)) + vars)) + + (( vars vals body) + ;; Try to allocate these procedures as labels. + (for-each (lambda (sym val) (hashq-set! labels sym (lambda-vars val))) + vars vals) + (hashq-set! bound-vars proc + (append (reverse vars) (hashq-ref bound-vars proc))) + ;; Step into subexpressions. + (let* ((var-refs + (map + ;; Since we're trying to label-allocate the lambda, + ;; pretend it's not a closure, and just recurse into its + ;; body directly. (Otherwise, recursing on a closure + ;; that references one of the fix's bound vars would + ;; prevent label allocation.) + (lambda (x) + (record-case x + (( (lvars vars) body) + (let ((locally-bound + (let rev* ((lvars lvars) (out '())) + (cond ((null? lvars) out) + ((pair? lvars) (rev* (cdr lvars) + (cons (car lvars) out))) + (else (cons lvars out)))))) + (hashq-set! bound-vars x locally-bound) + ;; recur/labels, the difference from the closure case + (let* ((referenced (recur/labels body x vars)) + (free (lset-difference eq? referenced locally-bound)) + (all-bound (reverse! (hashq-ref bound-vars x)))) + (hashq-set! bound-vars x all-bound) + (hashq-set! free-vars x free) + free))))) + vals)) + (vars-with-refs (map cons vars var-refs)) + (body-refs (recur/labels body proc vars))) + (define (delabel-dependents! sym) + (let ((refs (assq-ref vars-with-refs sym))) + (if refs + (for-each (lambda (sym) + (if (hashq-ref labels sym) + (begin + (hashq-set! labels sym #f) + (delabel-dependents! sym)))) + refs)))) + ;; Stepping into the lambdas and the body might have made some + ;; procedures not label-allocatable -- which might have + ;; knock-on effects. For example: + ;; (fix ((a (lambda () (b))) + ;; (b (lambda () a))) + ;; (a)) + ;; As far as `a' is concerned, both `a' and `b' are + ;; label-allocatable. But `b' references `a' not in a proc-tail + ;; position, which makes `a' not label-allocatable. The + ;; knock-on effect is that, when back-propagating this + ;; information to `a', `b' will also become not + ;; label-allocatable, as it is referenced within `a', which is + ;; allocated as a closure. This is a transitive relationship. + (for-each (lambda (sym) + (if (not (hashq-ref labels sym)) + (delabel-dependents! sym))) + vars) + ;; Now lift bound variables with label-allocated lambdas to the + ;; parent procedure. + (for-each + (lambda (sym val) + (if (hashq-ref labels sym) + ;; Remove traces of the label-bound lambda. The free + ;; vars will propagate up via the return val. + (begin + (hashq-set! bound-vars proc + (append (hashq-ref bound-vars val) + (hashq-ref bound-vars proc))) + (hashq-remove! bound-vars val) + (hashq-remove! free-vars val)))) + vars vals) + (lset-difference eq? + (apply lset-union eq? body-refs var-refs) + vars))) + + (( vars exp body) + (let ((bound (let lp ((out (hashq-ref bound-vars proc)) (in vars)) + (if (pair? in) + (lp (cons (car in) out) (cdr in)) + (if (null? in) out (cons in out)))))) + (hashq-set! bound-vars proc bound) + (lset-difference eq? + (lset-union eq? (step exp) (step-tail body)) + bound))) + + (else '()))) + + ;; allocation: sym -> {lambda -> address} + ;; lambda -> (nlocs labels . free-locs) + (define allocation (make-hash-table)) + + (define (allocate! x proc n) + (define (recur y) (allocate! y proc n)) + (record-case x + (( proc args) + (apply max (recur proc) (map recur args))) + + (( test then else) + (max (recur test) (recur then) (recur else))) + + (( name gensym exp) + (recur exp)) + + (( mod name public? exp) + (recur exp)) + + (( name exp) + (recur exp)) + + (( name exp) + (recur exp)) + + (( exps) + (apply max (map recur exps))) + + (( vars meta body) + ;; allocate closure vars in order + (let lp ((c (hashq-ref free-vars x)) (n 0)) + (if (pair? c) + (begin + (hashq-set! (hashq-ref allocation (car c)) + x + `(#f ,(hashq-ref assigned (car c)) . ,n)) + (lp (cdr c) (1+ n))))) + + (let ((nlocs + (let lp ((vars vars) (n 0)) + (if (not (null? vars)) + ;; allocate args + (let ((v (if (pair? vars) (car vars) vars))) + (hashq-set! allocation v + (make-hashq + x `(#t ,(hashq-ref assigned v) . ,n))) + (lp (if (pair? vars) (cdr vars) '()) (1+ n))) + ;; allocate body, return number of additional locals + (- (allocate! body x n) n)))) + (free-addresses + (map (lambda (v) + (hashq-ref (hashq-ref allocation v) proc)) + (hashq-ref free-vars x))) + (labels (filter cdr + (map (lambda (sym) + (cons sym (hashq-ref labels sym))) + (hashq-ref bound-vars x))))) + ;; set procedure allocations + (hashq-set! allocation x (cons* nlocs labels free-addresses))) + n) + + (( vars vals body) + (let ((nmax (apply max (map recur vals)))) + (cond + ;; the `or' hack + ((and (conditional? body) + (= (length vars) 1) + (let ((v (car vars))) + (and (not (hashq-ref assigned v)) + (= (hashq-ref refcounts v 0) 2) + (lexical-ref? (conditional-test body)) + (eq? (lexical-ref-gensym (conditional-test body)) v) + (lexical-ref? (conditional-then body)) + (eq? (lexical-ref-gensym (conditional-then body)) v)))) + (hashq-set! allocation (car vars) + (make-hashq proc `(#t #f . ,n))) + ;; the 1+ for this var + (max nmax (1+ n) (allocate! (conditional-else body) proc n))) + (else + (let lp ((vars vars) (n n)) + (if (null? vars) + (max nmax (allocate! body proc n)) + (let ((v (car vars))) + (hashq-set! + allocation v + (make-hashq proc + `(#t ,(hashq-ref assigned v) . ,n))) + (lp (cdr vars) (1+ n))))))))) + + (( vars vals body) + (let lp ((vars vars) (n n)) + (if (null? vars) + (let ((nmax (apply max + (map (lambda (x) + (allocate! x proc n)) + vals)))) + (max nmax (allocate! body proc n))) + (let ((v (car vars))) + (hashq-set! + allocation v + (make-hashq proc + `(#t ,(hashq-ref assigned v) . ,n))) + (lp (cdr vars) (1+ n)))))) + + (( vars vals body) + (let lp ((in vars) (n n)) + (if (null? in) + (let lp ((vars vars) (vals vals) (nmax n)) + (cond + ((null? vars) + (max nmax (allocate! body proc n))) + ((hashq-ref labels (car vars)) + ;; allocate label bindings & body inline to proc + (lp (cdr vars) + (cdr vals) + (record-case (car vals) + (( vars body) + (let lp ((vars vars) (n n)) + (if (not (null? vars)) + ;; allocate bindings + (let ((v (if (pair? vars) (car vars) vars))) + (hashq-set! + allocation v + (make-hashq + proc `(#t ,(hashq-ref assigned v) . ,n))) + (lp (if (pair? vars) (cdr vars) '()) (1+ n))) + ;; allocate body + (max nmax (allocate! body proc n)))))))) + (else + ;; allocate closure + (lp (cdr vars) + (cdr vals) + (max nmax (allocate! (car vals) proc n)))))) + + (let ((v (car in))) + (cond + ((hashq-ref assigned v) + (error "fixpoint procedures may not be assigned" x)) + ((hashq-ref labels v) + ;; no binding, it's a label + (lp (cdr in) n)) + (else + ;; allocate closure binding + (hashq-set! allocation v (make-hashq proc `(#t #f . ,n))) + (lp (cdr in) (1+ n)))))))) + + (( vars exp body) + (let ((nmax (recur exp))) + (let lp ((vars vars) (n n)) + (cond + ((null? vars) + (max nmax (allocate! body proc n))) + ((not (pair? vars)) + (hashq-set! allocation vars + (make-hashq proc + `(#t ,(hashq-ref assigned vars) . ,n))) + ;; the 1+ for this var + (max nmax (allocate! body proc (1+ n)))) + (else + (let ((v (car vars))) + (hashq-set! + allocation v + (make-hashq proc + `(#t ,(hashq-ref assigned v) . ,n))) + (lp (cdr vars) (1+ n)))))))) + + (else n))) + + (analyze! x #f '() #t #f) + (allocate! x #f 0) + + allocation) + + +;;; +;;; Unused variable analysis. +;;; + +;; records are used during tree traversals in +;; `report-unused-variables'. They contain a list of the local vars +;; currently in scope, a list of locals vars that have been referenced, and a +;; "location stack" (the stack of `tree-il-src' values for each parent tree). +(define-record-type + (make-binding-info vars refs locs) + binding-info? + (vars binding-info-vars) ;; ((GENSYM NAME LOCATION) ...) + (refs binding-info-refs) ;; (GENSYM ...) + (locs binding-info-locs)) ;; (LOCATION ...) + +(define (report-unused-variables tree) + "Report about unused variables in TREE. Return TREE." + + (define (dotless-list lst) + ;; If LST is a dotted list, return a proper list equal to LST except that + ;; the very last element is a pair; otherwise return LST. + (let loop ((lst lst) + (result '())) + (cond ((null? lst) + (reverse result)) + ((pair? lst) + (loop (cdr lst) (cons (car lst) result))) + (else + (loop '() (cons lst result)))))) + + (tree-il-fold (lambda (x info) + ;; X is a leaf: extend INFO's refs accordingly. + (let ((refs (binding-info-refs info)) + (vars (binding-info-vars info)) + (locs (binding-info-locs info))) + (record-case x + (( gensym) + (make-binding-info vars (cons gensym refs) locs)) + (else info)))) + + (lambda (x info) + ;; Going down into X: extend INFO's variable list + ;; accordingly. + (let ((refs (binding-info-refs info)) + (vars (binding-info-vars info)) + (locs (binding-info-locs info)) + (src (tree-il-src x))) + (define (extend inner-vars inner-names) + (append (map (lambda (var name) + (list var name src)) + inner-vars + inner-names) + vars)) + (record-case x + (( gensym) + (make-binding-info vars (cons gensym refs) + (cons src locs))) + (( vars names) + (let ((vars (dotless-list vars)) + (names (dotless-list names))) + (make-binding-info (extend vars names) refs + (cons src locs)))) + (( vars names) + (make-binding-info (extend vars names) refs + (cons src locs))) + (( vars names) + (make-binding-info (extend vars names) refs + (cons src locs))) + (( vars names) + (make-binding-info (extend vars names) refs + (cons src locs))) + (( vars names) + (make-binding-info (extend vars names) refs + (cons src locs))) + (else info)))) + + (lambda (x info) + ;; Leaving X's scope: shrink INFO's variable list + ;; accordingly and reported unused nested variables. + (let ((refs (binding-info-refs info)) + (vars (binding-info-vars info)) + (locs (binding-info-locs info))) + (define (shrink inner-vars refs) + (for-each (lambda (var) + (let ((gensym (car var))) + ;; Don't report lambda parameters as + ;; unused. + (if (and (not (memq gensym refs)) + (not (and (lambda? x) + (memq gensym + inner-vars)))) + (let ((name (cadr var)) + ;; We can get approximate + ;; source location by going up + ;; the LOCS location stack. + (loc (or (caddr var) + (find pair? locs)))) + (warning 'unused-variable loc name))))) + (filter (lambda (var) + (memq (car var) inner-vars)) + vars)) + (fold alist-delete vars inner-vars)) + + ;; For simplicity, we leave REFS untouched, i.e., with + ;; names of variables that are now going out of scope. + ;; It doesn't hurt as these are unique names, it just + ;; makes REFS unnecessarily fat. + (record-case x + (( vars) + (let ((vars (dotless-list vars))) + (make-binding-info (shrink vars refs) refs + (cdr locs)))) + (( vars) + (make-binding-info (shrink vars refs) refs + (cdr locs))) + (( vars) + (make-binding-info (shrink vars refs) refs + (cdr locs))) + (( vars) + (make-binding-info (shrink vars refs) refs + (cdr locs))) + (( vars) + (make-binding-info (shrink vars refs) refs + (cdr locs))) + (else info)))) + (make-binding-info '() '() '()) + tree) + tree) diff --git a/module/language/tree-il/compile-glil.scm b/module/language/tree-il/compile-glil.scm new file mode 100644 index 000000000..8886fa352 --- /dev/null +++ b/module/language/tree-il/compile-glil.scm @@ -0,0 +1,723 @@ +;;; TREE-IL -> GLIL compiler + +;; Copyright (C) 2001,2008,2009 Free Software Foundation, Inc. + +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +;;; Code: + +(define-module (language tree-il compile-glil) + #:use-module (system base syntax) + #:use-module (system base pmatch) + #:use-module (system base message) + #:use-module (ice-9 receive) + #:use-module (language glil) + #:use-module (system vm instruction) + #:use-module (language tree-il) + #:use-module (language tree-il optimize) + #:use-module (language tree-il analyze) + #:export (compile-glil)) + +;;; TODO: +;; +;; call-with-values -> mv-bind +;; basic degenerate-case reduction + +;; allocation: +;; sym -> {lambda -> address} +;; lambda -> (nlocs labels . free-locs) +;; +;; address := (local? boxed? . index) +;; free-locs ::= ((sym0 . address0) (sym1 . address1) ...) +;; free variable addresses are relative to parent proc. + +(define *comp-module* (make-fluid)) + +(define %warning-passes + `((unused-variable . ,report-unused-variables))) + +(define (compile-glil x e opts) + (define warnings + (or (and=> (memq #:warnings opts) cadr) + '())) + + ;; Go throught the warning passes. + (for-each (lambda (kind) + (let ((warn (assoc-ref %warning-passes kind))) + (and (procedure? warn) + (warn x)))) + warnings) + + (let* ((x (make-lambda (tree-il-src x) '() '() '() x)) + (x (optimize! x e opts)) + (allocation (analyze-lexicals x))) + + (with-fluid* *comp-module* (or (and e (car e)) (current-module)) + (lambda () + (values (flatten-lambda x #f allocation) + (and e (cons (car e) (cddr e))) + e))))) + + + +(define *primcall-ops* (make-hash-table)) +(for-each + (lambda (x) (hash-set! *primcall-ops* (car x) (cdr x))) + '(((eq? . 2) . eq?) + ((eqv? . 2) . eqv?) + ((equal? . 2) . equal?) + ((= . 2) . ee?) + ((< . 2) . lt?) + ((> . 2) . gt?) + ((<= . 2) . le?) + ((>= . 2) . ge?) + ((+ . 2) . add) + ((- . 2) . sub) + ((1+ . 1) . add1) + ((1- . 1) . sub1) + ((* . 2) . mul) + ((/ . 2) . div) + ((quotient . 2) . quo) + ((remainder . 2) . rem) + ((modulo . 2) . mod) + ((not . 1) . not) + ((pair? . 1) . pair?) + ((cons . 2) . cons) + ((car . 1) . car) + ((cdr . 1) . cdr) + ((set-car! . 2) . set-car!) + ((set-cdr! . 2) . set-cdr!) + ((null? . 1) . null?) + ((list? . 1) . list?) + (list . list) + (vector . vector) + ((@slot-ref . 2) . slot-ref) + ((@slot-set! . 3) . slot-set) + ((vector-ref . 2) . vector-ref) + ((vector-set! . 3) . vector-set) + + ((bytevector-u8-ref . 2) . bv-u8-ref) + ((bytevector-u8-set! . 3) . bv-u8-set) + ((bytevector-s8-ref . 2) . bv-s8-ref) + ((bytevector-s8-set! . 3) . bv-s8-set) + + ((bytevector-u16-ref . 3) . bv-u16-ref) + ((bytevector-u16-set! . 4) . bv-u16-set) + ((bytevector-u16-native-ref . 2) . bv-u16-native-ref) + ((bytevector-u16-native-set! . 3) . bv-u16-native-set) + ((bytevector-s16-ref . 3) . bv-s16-ref) + ((bytevector-s16-set! . 4) . bv-s16-set) + ((bytevector-s16-native-ref . 2) . bv-s16-native-ref) + ((bytevector-s16-native-set! . 3) . bv-s16-native-set) + + ((bytevector-u32-ref . 3) . bv-u32-ref) + ((bytevector-u32-set! . 4) . bv-u32-set) + ((bytevector-u32-native-ref . 2) . bv-u32-native-ref) + ((bytevector-u32-native-set! . 3) . bv-u32-native-set) + ((bytevector-s32-ref . 3) . bv-s32-ref) + ((bytevector-s32-set! . 4) . bv-s32-set) + ((bytevector-s32-native-ref . 2) . bv-s32-native-ref) + ((bytevector-s32-native-set! . 3) . bv-s32-native-set) + + ((bytevector-u64-ref . 3) . bv-u64-ref) + ((bytevector-u64-set! . 4) . bv-u64-set) + ((bytevector-u64-native-ref . 2) . bv-u64-native-ref) + ((bytevector-u64-native-set! . 3) . bv-u64-native-set) + ((bytevector-s64-ref . 3) . bv-s64-ref) + ((bytevector-s64-set! . 4) . bv-s64-set) + ((bytevector-s64-native-ref . 2) . bv-s64-native-ref) + ((bytevector-s64-native-set! . 3) . bv-s64-native-set) + + ((bytevector-ieee-single-ref . 3) . bv-f32-ref) + ((bytevector-ieee-single-set! . 4) . bv-f32-set) + ((bytevector-ieee-single-native-ref . 2) . bv-f32-native-ref) + ((bytevector-ieee-single-native-set! . 3) . bv-f32-native-set) + ((bytevector-ieee-double-ref . 3) . bv-f64-ref) + ((bytevector-ieee-double-set! . 4) . bv-f64-set) + ((bytevector-ieee-double-native-ref . 2) . bv-f64-native-ref) + ((bytevector-ieee-double-native-set! . 3) . bv-f64-native-set))) + + + + +(define (make-label) (gensym ":L")) + +(define (vars->bind-list ids vars allocation proc) + (map (lambda (id v) + (pmatch (hashq-ref (hashq-ref allocation v) proc) + ((#t ,boxed? . ,n) + (list id boxed? n)) + (,x (error "badness" x)))) + ids + vars)) + +;; FIXME: always emit? otherwise it's hard to pair bind with unbind +(define (emit-bindings src ids vars allocation proc emit-code) + (emit-code src (make-glil-bind + (vars->bind-list ids vars allocation proc)))) + +(define (with-output-to-code proc) + (let ((out '())) + (define (emit-code src x) + (set! out (cons x out)) + (if src + (set! out (cons (make-glil-source src) out)))) + (proc emit-code) + (reverse out))) + +(define (flatten-lambda x self-label allocation) + (receive (ids vars nargs nrest) + (let lp ((ids (lambda-names x)) (vars (lambda-vars x)) + (oids '()) (ovars '()) (n 0)) + (cond ((null? vars) (values (reverse oids) (reverse ovars) n 0)) + ((pair? vars) (lp (cdr ids) (cdr vars) + (cons (car ids) oids) (cons (car vars) ovars) + (1+ n))) + (else (values (reverse (cons ids oids)) + (reverse (cons vars ovars)) + (1+ n) 1)))) + (let ((nlocs (car (hashq-ref allocation x))) + (labels (cadr (hashq-ref allocation x)))) + (make-glil-program + nargs nrest nlocs (lambda-meta x) + (with-output-to-code + (lambda (emit-code) + ;; emit label for self tail calls + (if self-label + (emit-code #f (make-glil-label self-label))) + ;; write bindings and source debugging info + (if (not (null? ids)) + (emit-bindings #f ids vars allocation x emit-code)) + (if (lambda-src x) + (emit-code #f (make-glil-source (lambda-src x)))) + ;; box args if necessary + (for-each + (lambda (v) + (pmatch (hashq-ref (hashq-ref allocation v) x) + ((#t #t . ,n) + (emit-code #f (make-glil-lexical #t #f 'ref n)) + (emit-code #f (make-glil-lexical #t #t 'box n))))) + vars) + ;; and here, here, dear reader: we compile. + (flatten (lambda-body x) allocation x self-label + labels emit-code))))))) + +(define (flatten x allocation self self-label fix-labels emit-code) + (define (emit-label label) + (emit-code #f (make-glil-label label))) + (define (emit-branch src inst label) + (emit-code src (make-glil-branch inst label))) + + ;; RA: "return address"; #f unless we're in a non-tail fix with labels + ;; MVRA: "multiple-values return address"; #f unless we're in a let-values + (let comp ((x x) (context 'tail) (RA #f) (MVRA #f)) + (define (comp-tail tree) (comp tree context RA MVRA)) + (define (comp-push tree) (comp tree 'push #f #f)) + (define (comp-drop tree) (comp tree 'drop #f #f)) + (define (comp-vals tree MVRA) (comp tree 'vals #f MVRA)) + (define (comp-fix tree RA) (comp tree context RA MVRA)) + + ;; A couple of helpers. Note that if we are in tail context, we + ;; won't have an RA. + (define (maybe-emit-return) + (if RA + (emit-branch #f 'br RA) + (if (eq? context 'tail) + (emit-code #f (make-glil-call 'return 1))))) + + (record-case x + (() + (case context + ((push vals tail) + (emit-code #f (make-glil-void)))) + (maybe-emit-return)) + + (( src exp) + (case context + ((push vals tail) + (emit-code src (make-glil-const exp)))) + (maybe-emit-return)) + + ;; FIXME: should represent sequence as exps tail + (( src exps) + (let lp ((exps exps)) + (if (null? (cdr exps)) + (comp-tail (car exps)) + (begin + (comp-drop (car exps)) + (lp (cdr exps)))))) + + (( src proc args) + ;; FIXME: need a better pattern-matcher here + (cond + ((and (primitive-ref? proc) + (eq? (primitive-ref-name proc) '@apply) + (>= (length args) 1)) + (let ((proc (car args)) + (args (cdr args))) + (cond + ((and (primitive-ref? proc) (eq? (primitive-ref-name proc) 'values) + (not (eq? context 'push)) (not (eq? context 'vals))) + ;; tail: (lambda () (apply values '(1 2))) + ;; drop: (lambda () (apply values '(1 2)) 3) + ;; push: (lambda () (list (apply values '(10 12)) 1)) + (case context + ((drop) (for-each comp-drop args) (maybe-emit-return)) + ((tail) + (for-each comp-push args) + (emit-code src (make-glil-call 'return/values* (length args)))))) + + (else + (case context + ((tail) + (comp-push proc) + (for-each comp-push args) + (emit-code src (make-glil-call 'goto/apply (1+ (length args))))) + ((push) + (comp-push proc) + (for-each comp-push args) + (emit-code src (make-glil-call 'apply (1+ (length args)))) + (maybe-emit-return)) + ((vals) + (comp-vals + (make-application src (make-primitive-ref #f 'apply) + (cons proc args)) + MVRA) + (maybe-emit-return)) + ((drop) + ;; Well, shit. The proc might return any number of + ;; values (including 0), since it's in a drop context, + ;; yet apply does not create a MV continuation. So we + ;; mv-call out to our trampoline instead. + (comp-drop + (make-application src (make-primitive-ref #f 'apply) + (cons proc args))) + (maybe-emit-return))))))) + + ((and (primitive-ref? proc) (eq? (primitive-ref-name proc) 'values) + (not (eq? context 'push))) + ;; tail: (lambda () (values '(1 2))) + ;; drop: (lambda () (values '(1 2)) 3) + ;; push: (lambda () (list (values '(10 12)) 1)) + ;; vals: (let-values (((a b ...) (values 1 2 ...))) ...) + (case context + ((drop) (for-each comp-drop args) (maybe-emit-return)) + ((vals) + (for-each comp-push args) + (emit-code #f (make-glil-const (length args))) + (emit-branch src 'br MVRA)) + ((tail) + (for-each comp-push args) + (emit-code src (make-glil-call 'return/values (length args)))))) + + ((and (primitive-ref? proc) + (eq? (primitive-ref-name proc) '@call-with-values) + (= (length args) 2)) + ;; CONSUMER + ;; PRODUCER + ;; (mv-call MV) + ;; ([tail]-call 1) + ;; goto POST + ;; MV: [tail-]call/nargs + ;; POST: (maybe-drop) + (case context + ((vals) + ;; Fall back. + (comp-vals + (make-application src (make-primitive-ref #f 'call-with-values) + args) + MVRA) + (maybe-emit-return)) + (else + (let ((MV (make-label)) (POST (make-label)) + (producer (car args)) (consumer (cadr args))) + (comp-push consumer) + (comp-push producer) + (emit-code src (make-glil-mv-call 0 MV)) + (case context + ((tail) (emit-code src (make-glil-call 'goto/args 1))) + (else (emit-code src (make-glil-call 'call 1)) + (emit-branch #f 'br POST))) + (emit-label MV) + (case context + ((tail) (emit-code src (make-glil-call 'goto/nargs 0))) + (else (emit-code src (make-glil-call 'call/nargs 0)) + (emit-label POST) + (if (eq? context 'drop) + (emit-code #f (make-glil-call 'drop 1))) + (maybe-emit-return))))))) + + ((and (primitive-ref? proc) + (eq? (primitive-ref-name proc) '@call-with-current-continuation) + (= (length args) 1)) + (case context + ((tail) + (comp-push (car args)) + (emit-code src (make-glil-call 'goto/cc 1))) + ((vals) + (comp-vals + (make-application + src (make-primitive-ref #f 'call-with-current-continuation) + args) + MVRA) + (maybe-emit-return)) + ((push) + (comp-push (car args)) + (emit-code src (make-glil-call 'call/cc 1)) + (maybe-emit-return)) + ((drop) + ;; Crap. Just like `apply' in drop context. + (comp-drop + (make-application + src (make-primitive-ref #f 'call-with-current-continuation) + args)) + (maybe-emit-return)))) + + ((and (primitive-ref? proc) + (or (hash-ref *primcall-ops* + (cons (primitive-ref-name proc) (length args))) + (hash-ref *primcall-ops* (primitive-ref-name proc)))) + => (lambda (op) + (for-each comp-push args) + (emit-code src (make-glil-call op (length args))) + (case (instruction-pushes op) + ((0) + (case context + ((tail push vals) (emit-code #f (make-glil-void)))) + (maybe-emit-return)) + ((1) + (case context + ((drop) (emit-code #f (make-glil-call 'drop 1)))) + (maybe-emit-return)) + (else + (error "bad primitive op: too many pushes" + op (instruction-pushes op)))))) + + ;; da capo al fine + ((and (lexical-ref? proc) + self-label (eq? (lexical-ref-gensym proc) self-label) + ;; self-call in tail position is a goto + (eq? context 'tail) + ;; make sure the arity is right + (list? (lambda-vars self)) + (= (length args) (length (lambda-vars self)))) + ;; evaluate new values + (for-each comp-push args) + ;; rename & goto + (for-each (lambda (sym) + (pmatch (hashq-ref (hashq-ref allocation sym) self) + ((#t ,boxed? . ,index) + ;; set unboxed, as the proc prelude will box if needed + (emit-code #f (make-glil-lexical #t #f 'set index))) + (,x (error "what" x)))) + (reverse (lambda-vars self))) + (emit-branch src 'br self-label)) + + ;; lambda, the ultimate goto + ((and (lexical-ref? proc) + (assq (lexical-ref-gensym proc) fix-labels)) + ;; evaluate new values, assuming that analyze-lexicals did its + ;; job, and that the arity was right + (for-each comp-push args) + ;; rename + (for-each (lambda (sym) + (pmatch (hashq-ref (hashq-ref allocation sym) self) + ((#t #f . ,index) + (emit-code #f (make-glil-lexical #t #f 'set index))) + ((#t #t . ,index) + (emit-code #f (make-glil-lexical #t #t 'box index))) + (,x (error "what" x)))) + (reverse (assq-ref fix-labels (lexical-ref-gensym proc)))) + ;; goto! + (emit-branch src 'br (lexical-ref-gensym proc))) + + (else + (comp-push proc) + (for-each comp-push args) + (let ((len (length args))) + (case context + ((tail) (emit-code src (make-glil-call 'goto/args len))) + ((push) (emit-code src (make-glil-call 'call len)) + (maybe-emit-return)) + ((vals) (emit-code src (make-glil-mv-call len MVRA)) + (maybe-emit-return)) + ((drop) (let ((MV (make-label)) (POST (make-label))) + (emit-code src (make-glil-mv-call len MV)) + (emit-code #f (make-glil-call 'drop 1)) + (emit-branch #f 'br (or RA POST)) + (emit-label MV) + (emit-code #f (make-glil-mv-bind '() #f)) + (emit-code #f (make-glil-unbind)) + (if RA + (emit-branch #f 'br RA) + (emit-label POST))))))))) + + (( src test then else) + ;; TEST + ;; (br-if-not L1) + ;; THEN + ;; (br L2) + ;; L1: ELSE + ;; L2: + (let ((L1 (make-label)) (L2 (make-label))) + (comp-push test) + (emit-branch src 'br-if-not L1) + (comp-tail then) + ;; if there is an RA, comp-tail will cause a jump to it -- just + ;; have to clean up here if there is no RA. + (if (and (not RA) (not (eq? context 'tail))) + (emit-branch #f 'br L2)) + (emit-label L1) + (comp-tail else) + (if (and (not RA) (not (eq? context 'tail))) + (emit-label L2)))) + + (( src name) + (cond + ((eq? (module-variable (fluid-ref *comp-module*) name) + (module-variable the-root-module name)) + (case context + ((tail push vals) + (emit-code src (make-glil-toplevel 'ref name)))) + (maybe-emit-return)) + ((module-variable the-root-module name) + (case context + ((tail push vals) + (emit-code src (make-glil-module 'ref '(guile) name #f)))) + (maybe-emit-return)) + (else + (case context + ((tail push vals) + (emit-code src (make-glil-module + 'ref (module-name (fluid-ref *comp-module*)) name #f)))) + (maybe-emit-return)))) + + (( src name gensym) + (case context + ((push vals tail) + (pmatch (hashq-ref (hashq-ref allocation gensym) self) + ((,local? ,boxed? . ,index) + (emit-code src (make-glil-lexical local? boxed? 'ref index))) + (,loc + (error "badness" x loc))))) + (maybe-emit-return)) + + (( src name gensym exp) + (comp-push exp) + (pmatch (hashq-ref (hashq-ref allocation gensym) self) + ((,local? ,boxed? . ,index) + (emit-code src (make-glil-lexical local? boxed? 'set index))) + (,loc + (error "badness" x loc))) + (case context + ((tail push vals) + (emit-code #f (make-glil-void)))) + (maybe-emit-return)) + + (( src mod name public?) + (emit-code src (make-glil-module 'ref mod name public?)) + (case context + ((drop) (emit-code #f (make-glil-call 'drop 1)))) + (maybe-emit-return)) + + (( src mod name public? exp) + (comp-push exp) + (emit-code src (make-glil-module 'set mod name public?)) + (case context + ((tail push vals) + (emit-code #f (make-glil-void)))) + (maybe-emit-return)) + + (( src name) + (emit-code src (make-glil-toplevel 'ref name)) + (case context + ((drop) (emit-code #f (make-glil-call 'drop 1)))) + (maybe-emit-return)) + + (( src name exp) + (comp-push exp) + (emit-code src (make-glil-toplevel 'set name)) + (case context + ((tail push vals) + (emit-code #f (make-glil-void)))) + (maybe-emit-return)) + + (( src name exp) + (comp-push exp) + (emit-code src (make-glil-toplevel 'define name)) + (case context + ((tail push vals) + (emit-code #f (make-glil-void)))) + (maybe-emit-return)) + + (() + (let ((free-locs (cddr (hashq-ref allocation x)))) + (case context + ((push vals tail) + (emit-code #f (flatten-lambda x #f allocation)) + (if (not (null? free-locs)) + (begin + (for-each + (lambda (loc) + (pmatch loc + ((,local? ,boxed? . ,n) + (emit-code #f (make-glil-lexical local? #f 'ref n))) + (else (error "what" x loc)))) + free-locs) + (emit-code #f (make-glil-call 'vector (length free-locs))) + (emit-code #f (make-glil-call 'make-closure 2))))))) + (maybe-emit-return)) + + (( src names vars vals body) + (for-each comp-push vals) + (emit-bindings src names vars allocation self emit-code) + (for-each (lambda (v) + (pmatch (hashq-ref (hashq-ref allocation v) self) + ((#t #f . ,n) + (emit-code src (make-glil-lexical #t #f 'set n))) + ((#t #t . ,n) + (emit-code src (make-glil-lexical #t #t 'box n))) + (,loc (error "badness" x loc)))) + (reverse vars)) + (comp-tail body) + (emit-code #f (make-glil-unbind))) + + (( src names vars vals body) + (for-each (lambda (v) + (pmatch (hashq-ref (hashq-ref allocation v) self) + ((#t #t . ,n) + (emit-code src (make-glil-lexical #t #t 'empty-box n))) + (,loc (error "badness" x loc)))) + vars) + (for-each comp-push vals) + (emit-bindings src names vars allocation self emit-code) + (for-each (lambda (v) + (pmatch (hashq-ref (hashq-ref allocation v) self) + ((#t #t . ,n) + (emit-code src (make-glil-lexical #t #t 'set n))) + (,loc (error "badness" x loc)))) + (reverse vars)) + (comp-tail body) + (emit-code #f (make-glil-unbind))) + + (( src names vars vals body) + ;; The ideal here is to just render the lambda bodies inline, and + ;; wire the code together with gotos. We can do that if + ;; analyze-lexicals has determined that a given var has "label" + ;; allocation -- which is the case if it is in `fix-labels'. + ;; + ;; But even for closures that we can't inline, we can do some + ;; tricks to avoid heap-allocation for the binding itself. Since + ;; we know the vals are lambdas, we can set them to their local + ;; var slots first, then capture their bindings, mutating them in + ;; place. + (let ((RA (if (eq? context 'tail) #f (make-label)))) + (for-each + (lambda (x v) + (cond + ((hashq-ref allocation x) + ;; allocating a closure + (emit-code #f (flatten-lambda x v allocation)) + (if (not (null? (cddr (hashq-ref allocation x)))) + ;; Need to make-closure first, but with a temporary #f + ;; free-variables vector, so we are mutating fresh + ;; closures on the heap. + (begin + (emit-code #f (make-glil-const #f)) + (emit-code #f (make-glil-call 'make-closure 2)))) + (pmatch (hashq-ref (hashq-ref allocation v) self) + ((#t #f . ,n) + (emit-code src (make-glil-lexical #t #f 'set n))) + (,loc (error "badness" x loc)))) + (else + ;; labels allocation: emit label & body, but jump over it + (let ((POST (make-label))) + (emit-branch #f 'br POST) + (emit-label v) + ;; we know the lambda vars are a list + (emit-bindings #f (lambda-names x) (lambda-vars x) + allocation self emit-code) + (if (lambda-src x) + (emit-code #f (make-glil-source (lambda-src x)))) + (comp-fix (lambda-body x) RA) + (emit-code #f (make-glil-unbind)) + (emit-label POST))))) + vals + vars) + ;; Emit bindings metadata for closures + (let ((binds (let lp ((out '()) (vars vars) (names names)) + (cond ((null? vars) (reverse! out)) + ((assq (car vars) fix-labels) + (lp out (cdr vars) (cdr names))) + (else + (lp (acons (car vars) (car names) out) + (cdr vars) (cdr names))))))) + (emit-bindings src (map cdr binds) (map car binds) + allocation self emit-code)) + ;; Now go back and fix up the bindings for closures. + (for-each + (lambda (x v) + (let ((free-locs (if (hashq-ref allocation x) + (cddr (hashq-ref allocation x)) + ;; can hit this latter case for labels allocation + '()))) + (if (not (null? free-locs)) + (begin + (for-each + (lambda (loc) + (pmatch loc + ((,local? ,boxed? . ,n) + (emit-code #f (make-glil-lexical local? #f 'ref n))) + (else (error "what" x loc)))) + free-locs) + (emit-code #f (make-glil-call 'vector (length free-locs))) + (pmatch (hashq-ref (hashq-ref allocation v) self) + ((#t #f . ,n) + (emit-code #f (make-glil-lexical #t #f 'fix n))) + (,loc (error "badness" x loc))))))) + vals + vars) + (comp-tail body) + (emit-label RA) + (emit-code #f (make-glil-unbind)))) + + (( src names vars exp body) + (let lp ((names '()) (vars '()) (inames names) (ivars vars) (rest? #f)) + (cond + ((pair? inames) + (lp (cons (car inames) names) (cons (car ivars) vars) + (cdr inames) (cdr ivars) #f)) + ((not (null? inames)) + (lp (cons inames names) (cons ivars vars) '() '() #t)) + (else + (let ((names (reverse! names)) + (vars (reverse! vars)) + (MV (make-label))) + (comp-vals exp MV) + (emit-code #f (make-glil-const 1)) + (emit-label MV) + (emit-code src (make-glil-mv-bind + (vars->bind-list names vars allocation self) + rest?)) + (for-each (lambda (v) + (pmatch (hashq-ref (hashq-ref allocation v) self) + ((#t #f . ,n) + (emit-code src (make-glil-lexical #t #f 'set n))) + ((#t #t . ,n) + (emit-code src (make-glil-lexical #t #t 'box n))) + (,loc (error "badness" x loc)))) + (reverse vars)) + (comp-tail body) + (emit-code #f (make-glil-unbind)))))))))) diff --git a/module/language/tree-il/fix-letrec.scm b/module/language/tree-il/fix-letrec.scm new file mode 100644 index 000000000..9b66d9ed5 --- /dev/null +++ b/module/language/tree-il/fix-letrec.scm @@ -0,0 +1,240 @@ +;;; transformation of letrec into simpler forms + +;; Copyright (C) 2009 Free Software Foundation, Inc. + +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +(define-module (language tree-il fix-letrec) + #:use-module (system base syntax) + #:use-module (srfi srfi-1) + #:use-module (srfi srfi-11) + #:use-module (language tree-il) + #:use-module (language tree-il primitives) + #:export (fix-letrec!)) + +;; For a detailed discussion, see "Fixing Letrec: A Faithful Yet +;; Efficient Implementation of Scheme’s Recursive Binding Construct", by +;; Oscar Waddell, Dipanwita Sarkar, and R. Kent Dybvig. + +(define fix-fold + (make-tree-il-folder unref ref set simple lambda complex)) + +(define (simple-expression? x bound-vars) + (record-case x + (() #t) + (() #t) + (( gensym) + (not (memq gensym bound-vars))) + (( test then else) + (and (simple-expression? test bound-vars) + (simple-expression? then bound-vars) + (simple-expression? else bound-vars))) + (( exps) + (and-map (lambda (x) (simple-expression? x bound-vars)) + exps)) + (( proc args) + (and (primitive-ref? proc) + (effect-free-primitive? (primitive-ref-name proc)) + (and-map (lambda (x) (simple-expression? x bound-vars)) + args))) + (else #f))) + +(define (partition-vars x) + (let-values + (((unref ref set simple lambda* complex) + (fix-fold x + (lambda (x unref ref set simple lambda* complex) + (record-case x + (( gensym) + (values (delq gensym unref) + (lset-adjoin eq? ref gensym) + set + simple + lambda* + complex)) + (( gensym) + (values unref + ref + (lset-adjoin eq? set gensym) + simple + lambda* + complex)) + (( vars) + (values (append vars unref) + ref + set + simple + lambda* + complex)) + (( vars) + (values (append vars unref) + ref + set + simple + lambda* + complex)) + (else + (values unref ref set simple lambda* complex)))) + (lambda (x unref ref set simple lambda* complex) + (record-case x + (( (orig-vars vars) vals) + (let lp ((vars orig-vars) (vals vals) + (s '()) (l '()) (c '())) + (cond + ((null? vars) + (values unref + ref + set + (append s simple) + (append l lambda*) + (append c complex))) + ((memq (car vars) unref) + (lp (cdr vars) (cdr vals) + s l c)) + ((memq (car vars) set) + (lp (cdr vars) (cdr vals) + s l (cons (car vars) c))) + ((lambda? (car vals)) + (lp (cdr vars) (cdr vals) + s (cons (car vars) l) c)) + ((simple-expression? (car vals) orig-vars) + (lp (cdr vars) (cdr vals) + (cons (car vars) s) l c)) + (else + (lp (cdr vars) (cdr vals) + s l (cons (car vars) c)))))) + (( (orig-vars vars) vals) + ;; The point is to compile let-bound lambdas as + ;; efficiently as we do letrec-bound lambdas, so + ;; we use the same algorithm for analyzing the + ;; vars. There is no problem recursing into the + ;; bindings after the let, because all variables + ;; have been renamed. + (let lp ((vars orig-vars) (vals vals) + (s '()) (l '()) (c '())) + (cond + ((null? vars) + (values unref + ref + set + (append s simple) + (append l lambda*) + (append c complex))) + ((memq (car vars) unref) + (lp (cdr vars) (cdr vals) + s l c)) + ((memq (car vars) set) + (lp (cdr vars) (cdr vals) + s l (cons (car vars) c))) + ((and (lambda? (car vals)) + (not (memq (car vars) set))) + (lp (cdr vars) (cdr vals) + s (cons (car vars) l) c)) + ;; There is no difference between simple and + ;; complex, for the purposes of let. Just lump + ;; them all into complex. + (else + (lp (cdr vars) (cdr vals) + s l (cons (car vars) c)))))) + (else + (values unref ref set simple lambda* complex)))) + '() + '() + '() + '() + '() + '()))) + (values unref simple lambda* complex))) + +(define (fix-letrec! x) + (let-values (((unref simple lambda* complex) (partition-vars x))) + (post-order! + (lambda (x) + (record-case x + + ;; Sets to unreferenced variables may be replaced by their + ;; expression, called for effect. + (( gensym exp) + (if (memq gensym unref) + (make-sequence #f (list exp (make-void #f))) + x)) + + (( src names vars vals body) + (let ((binds (map list vars names vals))) + (define (lookup set) + (map (lambda (v) (assq v binds)) + (lset-intersection eq? vars set))) + (let ((u (lookup unref)) + (s (lookup simple)) + (l (lookup lambda*)) + (c (lookup complex))) + ;; Bind "simple" bindings, and locations for complex + ;; bindings. + (make-let + src + (append (map cadr s) (map cadr c)) + (append (map car s) (map car c)) + (append (map caddr s) (map (lambda (x) (make-void #f)) c)) + ;; Bind lambdas using the fixpoint operator. + (make-fix + src (map cadr l) (map car l) (map caddr l) + (make-sequence + src + (append + ;; The right-hand-sides of the unreferenced + ;; bindings, for effect. + (map caddr u) + (if (null? c) + ;; No complex bindings, just emit the body. + (list body) + (list + ;; Evaluate the the "complex" bindings, in a `let' to + ;; indicate that order doesn't matter, and bind to + ;; their variables. + (let ((tmps (map (lambda (x) (gensym)) c))) + (make-let + #f (map cadr c) tmps (map caddr c) + (make-sequence + #f + (map (lambda (x tmp) + (make-lexical-set + #f (cadr x) (car x) + (make-lexical-ref #f (cadr x) tmp))) + c tmps)))) + ;; Finally, the body. + body))))))))) + + (( src names vars vals body) + (let ((binds (map list vars names vals))) + (define (lookup set) + (map (lambda (v) (assq v binds)) + (lset-intersection eq? vars set))) + (let ((u (lookup unref)) + (l (lookup lambda*)) + (c (lookup complex))) + (make-sequence + src + (append + ;; unreferenced bindings, called for effect. + (map caddr u) + (list + ;; unassigned lambdas use fix. + (make-fix src (map cadr l) (map car l) (map caddr l) + ;; and the "complex" bindings. + (make-let src (map cadr c) (map car c) (map caddr c) + body)))))))) + + (else x))) + x))) diff --git a/module/language/tree-il/inline.scm b/module/language/tree-il/inline.scm new file mode 100644 index 000000000..adc3f18bd --- /dev/null +++ b/module/language/tree-il/inline.scm @@ -0,0 +1,81 @@ +;;; a simple inliner + +;; Copyright (C) 2009 Free Software Foundation, Inc. + +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +(define-module (language tree-il inline) + #:use-module (system base syntax) + #:use-module (language tree-il) + #:export (inline!)) + +;; Possible optimizations: +;; * constant folding, propagation +;; * procedure inlining +;; * always when single call site +;; * always for "trivial" procs +;; * otherwise who knows +;; * dead code elimination +;; * degenerate case optimizations +;; * "fixing letrec" + +;; This is a completely brain-dead optimization pass whose sole claim to +;; fame is ((lambda () x)) => x. +(define (inline! x) + (post-order! + (lambda (x) + (record-case x + (( src proc args) + (cond + + ;; ((lambda () x)) => x + ((and (lambda? proc) (null? (lambda-vars proc)) + (null? args)) + (lambda-body proc)) + + ;; (call-with-values (lambda () foo) (lambda (a b . c) bar)) + ;; => (let-values (((a b . c) foo)) bar) + ;; + ;; Note that this is a singly-binding form of let-values. Also + ;; note that Scheme's let-values expands into call-with-values, + ;; then here we reduce it to tree-il's let-values. + ((and (primitive-ref? proc) + (eq? (primitive-ref-name proc) '@call-with-values) + (= (length args) 2) + (lambda? (cadr args))) + (let ((producer (car args)) + (consumer (cadr args))) + (make-let-values src + (lambda-names consumer) + (lambda-vars consumer) + (if (and (lambda? producer) + (null? (lambda-names producer))) + (lambda-body producer) + (make-application src producer '())) + (lambda-body consumer)))) + + (else #f))) + + (( vars body) + (if (null? vars) body x)) + + (( vars body) + (if (null? vars) body x)) + + (( vars body) + (if (null? vars) body x)) + + (else #f))) + x)) diff --git a/module/language/tree-il/optimize.scm b/module/language/tree-il/optimize.scm new file mode 100644 index 000000000..0e490a636 --- /dev/null +++ b/module/language/tree-il/optimize.scm @@ -0,0 +1,35 @@ +;;; Tree-il optimizer + +;; Copyright (C) 2009 Free Software Foundation, Inc. + +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +;;; Code: + +(define-module (language tree-il optimize) + #:use-module (language tree-il) + #:use-module (language tree-il primitives) + #:use-module (language tree-il inline) + #:use-module (language tree-il fix-letrec) + #:export (optimize!)) + +(define (env-module e) + (if e (car e) (current-module))) + +(define (optimize! x env opts) + (inline! + (fix-letrec! + (expand-primitives! + (resolve-primitives! x (env-module env)))))) diff --git a/module/language/tree-il/primitives.scm b/module/language/tree-il/primitives.scm new file mode 100644 index 000000000..955c7bf25 --- /dev/null +++ b/module/language/tree-il/primitives.scm @@ -0,0 +1,287 @@ +;;; open-coding primitive procedures + +;; Copyright (C) 2009 Free Software Foundation, Inc. + +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +;;; Code: + +(define-module (language tree-il primitives) + #:use-module (system base pmatch) + #:use-module (rnrs bytevector) + #:use-module (system base syntax) + #:use-module (language tree-il) + #:use-module (srfi srfi-16) + #:export (resolve-primitives! add-interesting-primitive! + expand-primitives! effect-free-primitive?)) + +(define *interesting-primitive-names* + '(apply @apply + call-with-values @call-with-values + call-with-current-continuation @call-with-current-continuation + call/cc + values + eq? eqv? equal? + = < > <= >= zero? + + * - / 1- 1+ quotient remainder modulo + not + pair? null? list? acons cons cons* + + list vector + + car cdr + set-car! set-cdr! + + caar cadr cdar cddr + + caaar caadr cadar caddr cdaar cdadr cddar cdddr + + caaaar caaadr caadar caaddr cadaar cadadr caddar cadddr + cdaaar cdaadr cdadar cdaddr cddaar cddadr cdddar cddddr + + vector-ref vector-set! + + bytevector-u8-ref bytevector-u8-set! + bytevector-s8-ref bytevector-s8-set! + + bytevector-u16-ref bytevector-u16-set! + bytevector-u16-native-ref bytevector-u16-native-set! + bytevector-s16-ref bytevector-s16-set! + bytevector-s16-native-ref bytevector-s16-native-set! + + bytevector-u32-ref bytevector-u32-set! + bytevector-u32-native-ref bytevector-u32-native-set! + bytevector-s32-ref bytevector-s32-set! + bytevector-s32-native-ref bytevector-s32-native-set! + + bytevector-u64-ref bytevector-u64-set! + bytevector-u64-native-ref bytevector-u64-native-set! + bytevector-s64-ref bytevector-s64-set! + bytevector-s64-native-ref bytevector-s64-native-set! + + bytevector-ieee-single-ref bytevector-ieee-single-set! + bytevector-ieee-single-native-ref bytevector-ieee-single-native-set! + bytevector-ieee-double-ref bytevector-ieee-double-set! + bytevector-ieee-double-native-ref bytevector-ieee-double-native-set!)) + +(define (add-interesting-primitive! name) + (hashq-set! *interesting-primitive-vars* + (module-variable (current-module) name) + name)) + +(define *interesting-primitive-vars* (make-hash-table)) + +(for-each add-interesting-primitive! *interesting-primitive-names*) + +(define *effect-free-primitives* + '(values + eq? eqv? equal? + = < > <= >= zero? + + * - / 1- 1+ quotient remainder modulo + not + pair? null? list? acons cons cons* + list vector + car cdr + caar cadr cdar cddr + caaar caadr cadar caddr cdaar cdadr cddar cdddr + caaaar caaadr caadar caaddr cadaar cadadr caddar cadddr + cdaaar cdaadr cdadar cdaddr cddaar cddadr cdddar cddddr + vector-ref + bytevector-u8-ref bytevector-s8-ref + bytevector-u16-ref bytevector-u16-native-ref + bytevector-s16-ref bytevector-s16-native-ref + bytevector-u32-ref bytevector-u32-native-ref + bytevector-s32-ref bytevector-s32-native-ref + bytevector-u64-ref bytevector-u64-native-ref + bytevector-s64-ref bytevector-s64-native-ref + bytevector-ieee-single-ref bytevector-ieee-single-native-ref + bytevector-ieee-double-ref bytevector-ieee-double-native-ref)) + + +(define *effect-free-primitive-table* (make-hash-table)) + +(for-each (lambda (x) (hashq-set! *effect-free-primitive-table* x #t)) + *effect-free-primitives*) + +(define (effect-free-primitive? prim) + (hashq-ref *effect-free-primitive-table* prim)) + +(define (resolve-primitives! x mod) + (post-order! + (lambda (x) + (record-case x + (( src name) + (and=> (hashq-ref *interesting-primitive-vars* + (module-variable mod name)) + (lambda (name) (make-primitive-ref src name)))) + (( src mod name public?) + ;; for the moment, we're disabling primitive resolution for + ;; public refs because resolve-interface can raise errors. + (let ((m (and (not public?) (resolve-module mod)))) + (and m + (and=> (hashq-ref *interesting-primitive-vars* + (module-variable m name)) + (lambda (name) (make-primitive-ref src name)))))) + (else #f))) + x)) + + + +(define *primitive-expand-table* (make-hash-table)) + +(define (expand-primitives! x) + (pre-order! + (lambda (x) + (record-case x + (( src proc args) + (and (primitive-ref? proc) + (let ((expand (hashq-ref *primitive-expand-table* + (primitive-ref-name proc)))) + (and expand (apply expand src args))))) + (else #f))) + x)) + +;;; I actually did spend about 10 minutes trying to redo this with +;;; syntax-rules. Patches appreciated. +;;; +(define-macro (define-primitive-expander sym . clauses) + (define (inline-args args) + (let lp ((in args) (out '())) + (cond ((null? in) `(list ,@(reverse out))) + ((symbol? in) `(cons* ,@(reverse out) ,in)) + ((pair? (car in)) + (lp (cdr in) + (cons `(make-application src (make-primitive-ref src ',(caar in)) + ,(inline-args (cdar in))) + out))) + ((symbol? (car in)) + ;; assume it's locally bound + (lp (cdr in) (cons (car in) out))) + ((number? (car in)) + (lp (cdr in) (cons `(make-const src ,(car in)) out))) + (else + (error "what what" (car in)))))) + (define (consequent exp) + (cond + ((pair? exp) + (pmatch exp + ((if ,test ,then ,else) + `(if ,test + ,(consequent then) + ,(consequent else))) + (else + `(make-application src (make-primitive-ref src ',(car exp)) + ,(inline-args (cdr exp)))))) + ((symbol? exp) + ;; assume locally bound + exp) + ((number? exp) + `(make-const src ,exp)) + (else (error "bad consequent yall" exp)))) + `(hashq-set! *primitive-expand-table* + ',sym + (case-lambda + ,@(let lp ((in clauses) (out '())) + (if (null? in) + (reverse (cons '(else #f) out)) + (lp (cddr in) + (cons `((src . ,(car in)) + ,(consequent (cadr in))) out))))))) + +(define-primitive-expander zero? (x) + (= x 0)) + +(define-primitive-expander + + () 0 + (x) x + (x y) (if (and (const? y) + (let ((y (const-exp y))) + (and (exact? y) (= y 1)))) + (1+ x) + (if (and (const? x) + (let ((x (const-exp x))) + (and (exact? x) (= x 1)))) + (1+ y) + (+ x y))) + (x y z . rest) (+ x (+ y z . rest))) + +(define-primitive-expander * + () 1 + (x) x + (x y z . rest) (* x (* y z . rest))) + +(define-primitive-expander - + (x) (- 0 x) + (x y) (if (and (const? y) + (let ((y (const-exp y))) + (and (exact? y) (= y 1)))) + (1- x) + (- x y)) + (x y z . rest) (- x (+ y z . rest))) + +(define-primitive-expander / + (x) (/ 1 x) + (x y z . rest) (/ x (* y z . rest))) + +(define-primitive-expander caar (x) (car (car x))) +(define-primitive-expander cadr (x) (car (cdr x))) +(define-primitive-expander cdar (x) (cdr (car x))) +(define-primitive-expander cddr (x) (cdr (cdr x))) +(define-primitive-expander caaar (x) (car (car (car x)))) +(define-primitive-expander caadr (x) (car (car (cdr x)))) +(define-primitive-expander cadar (x) (car (cdr (car x)))) +(define-primitive-expander caddr (x) (car (cdr (cdr x)))) +(define-primitive-expander cdaar (x) (cdr (car (car x)))) +(define-primitive-expander cdadr (x) (cdr (car (cdr x)))) +(define-primitive-expander cddar (x) (cdr (cdr (car x)))) +(define-primitive-expander cdddr (x) (cdr (cdr (cdr x)))) +(define-primitive-expander caaaar (x) (car (car (car (car x))))) +(define-primitive-expander caaadr (x) (car (car (car (cdr x))))) +(define-primitive-expander caadar (x) (car (car (cdr (car x))))) +(define-primitive-expander caaddr (x) (car (car (cdr (cdr x))))) +(define-primitive-expander cadaar (x) (car (cdr (car (car x))))) +(define-primitive-expander cadadr (x) (car (cdr (car (cdr x))))) +(define-primitive-expander caddar (x) (car (cdr (cdr (car x))))) +(define-primitive-expander cadddr (x) (car (cdr (cdr (cdr x))))) +(define-primitive-expander cdaaar (x) (cdr (car (car (car x))))) +(define-primitive-expander cdaadr (x) (cdr (car (car (cdr x))))) +(define-primitive-expander cdadar (x) (cdr (car (cdr (car x))))) +(define-primitive-expander cdaddr (x) (cdr (car (cdr (cdr x))))) +(define-primitive-expander cddaar (x) (cdr (cdr (car (car x))))) +(define-primitive-expander cddadr (x) (cdr (cdr (car (cdr x))))) +(define-primitive-expander cdddar (x) (cdr (cdr (cdr (car x))))) +(define-primitive-expander cddddr (x) (cdr (cdr (cdr (cdr x))))) + +(define-primitive-expander cons* + (x) x + (x y) (cons x y) + (x y . rest) (cons x (cons* y . rest))) + +(define-primitive-expander acons (x y z) + (cons (cons x y) z)) + +(define-primitive-expander apply (f . args) + (@apply f . args)) + +(define-primitive-expander call-with-values (producer consumer) + (@call-with-values producer consumer)) + +(define-primitive-expander call-with-current-continuation (proc) + (@call-with-current-continuation proc)) + +(define-primitive-expander call/cc (proc) + (@call-with-current-continuation proc)) + +(define-primitive-expander values (x) x) diff --git a/module/language/tree-il/spec.scm b/module/language/tree-il/spec.scm new file mode 100644 index 000000000..2d24f7bf6 --- /dev/null +++ b/module/language/tree-il/spec.scm @@ -0,0 +1,42 @@ +;;; Tree Intermediate Language + +;; Copyright (C) 2009 Free Software Foundation, Inc. + +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +;;; Code: + +(define-module (language tree-il spec) + #:use-module (system base language) + #:use-module (language glil) + #:use-module (language tree-il) + #:use-module (language tree-il compile-glil) + #:export (tree-il)) + +(define (write-tree-il exp . port) + (apply write (unparse-tree-il exp) port)) + +(define (join exps env) + (make-sequence #f exps)) + +(define-language tree-il + #:title "Tree Intermediate Language" + #:version "1.0" + #:reader read + #:printer write-tree-il + #:parser parse-tree-il + #:joiner join + #:compilers `((glil . ,compile-glil)) + ) diff --git a/module/language/value/spec.scm b/module/language/value/spec.scm index 51f5e6c66..aebba8c8d 100644 --- a/module/language/value/spec.scm +++ b/module/language/value/spec.scm @@ -2,20 +2,19 @@ ;; Copyright (C) 2001 Free Software Foundation, Inc. -;; 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 2, 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 COPYING. If not, write to -;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Code: diff --git a/module/oop/Makefile.am b/module/oop/Makefile.am deleted file mode 100644 index 83c342abc..000000000 --- a/module/oop/Makefile.am +++ /dev/null @@ -1,30 +0,0 @@ -## Process this file with automake to produce Makefile.in. -## -## Copyright (C) 2000, 2004, 2006, 2008 Free Software Foundation, Inc. -## -## This file is part of GUILE. -## -## GUILE 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, or -## (at your option) any later version. -## -## GUILE 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 GUILE; see the file COPYING. If not, write -## to the Free Software Foundation, Inc., 51 Franklin Street, Fifth -## Floor, Boston, MA 02110-1301 USA - -AUTOMAKE_OPTIONS = gnu - -SUBDIRS = goops - -modpath = oop -SOURCES = goops.scm -include $(top_srcdir)/am/guilec - -EXTRA_DIST += ChangeLog-2008 diff --git a/module/oop/goops.scm b/module/oop/goops.scm index 2254f93e5..c1754da3e 100644 --- a/module/oop/goops.scm +++ b/module/oop/goops.scm @@ -5,7 +5,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -154,17 +154,6 @@ ;;; SLOT-DEFINITION ::= SLOT-NAME | (SLOT-NAME OPTION ...) ;;; OPTION ::= KEYWORD VALUE ;;; -(define (define-class-pre-definition kw val) - (case kw - ((#:getter #:setter) - `(if (or (not (defined? ',val)) - (not (is-a? ,val ))) - (define-generic ,val))) - ((#:accessor) - `(if (or (not (defined? ',val)) - (not (is-a? ,val ))) - (define-accessor ,val))) - (else #f))) (define (kw-do-map mapper f kwargs) (define (keywords l) @@ -180,69 +169,6 @@ (a (args kwargs))) (mapper f k a))) -;;; This code should be implemented in C. -;;; -(define-macro (define-class name supers . slots) - ;; Some slot options require extra definitions to be made. In - ;; particular, we want to make sure that the generic function objects - ;; which represent accessors exist before `make-class' tries to add - ;; methods to them. - ;; - ;; Postpone some error handling to class macro. - ;; - `(begin - ;; define accessors - ,@(append-map (lambda (slot) - (kw-do-map filter-map - define-class-pre-definition - (if (pair? slot) (cdr slot) '()))) - (take-while (lambda (x) (not (keyword? x))) slots)) - (if (and (defined? ',name) - (is-a? ,name ) - (memq (class-precedence-list ,name))) - (class-redefinition ,name - (class ,supers ,@slots #:name ',name)) - (define ,name (class ,supers ,@slots #:name ',name))))) - -(define standard-define-class define-class) - -;;; (class (SUPER ...) SLOT-DEFINITION ... OPTION ...) -;;; -;;; SLOT-DEFINITION ::= SLOT-NAME | (SLOT-NAME OPTION ...) -;;; OPTION ::= KEYWORD VALUE -;;; -(define-macro (class supers . slots) - (define (make-slot-definition-forms slots) - (map - (lambda (def) - (cond - ((pair? def) - `(list ',(car def) - ,@(kw-do-map append-map - (lambda (kw arg) - (case kw - ((#:init-form) - `(#:init-form ',arg - #:init-thunk (lambda () ,arg))) - (else (list kw arg)))) - (cdr def)))) - (else - `(list ',def)))) - slots)) - - (if (not (list? supers)) - (goops-error "malformed superclass list: ~S" supers)) - (let ((slot-defs (cons #f '())) - (slots (take-while (lambda (x) (not (keyword? x))) slots)) - (options (or (find-tail keyword? slots) '()))) - `(make-class - ;; evaluate super class variables - (list ,@supers) - ;; evaluate slot definitions, except the slot name! - (list ,@(make-slot-definition-forms slots)) - ;; evaluate class options - ,@options))) - (define (make-class supers slots . options) (let ((env (or (get-keyword #:environment options #f) (top-level-env)))) @@ -275,6 +201,108 @@ #:environment env options)))) +;;; (class (SUPER ...) SLOT-DEFINITION ... OPTION ...) +;;; +;;; SLOT-DEFINITION ::= SLOT-NAME | (SLOT-NAME OPTION ...) +;;; OPTION ::= KEYWORD VALUE +;;; +(define-macro (class supers . slots) + (define (make-slot-definition-forms slots) + (map + (lambda (def) + (cond + ((pair? def) + `(list ',(car def) + ,@(kw-do-map append-map + (lambda (kw arg) + (case kw + ((#:init-form) + `(#:init-form ',arg + #:init-thunk (lambda () ,arg))) + (else (list kw arg)))) + (cdr def)))) + (else + `(list ',def)))) + slots)) + (if (not (list? supers)) + (goops-error "malformed superclass list: ~S" supers)) + (let ((slot-defs (cons #f '())) + (slots (take-while (lambda (x) (not (keyword? x))) slots)) + (options (or (find-tail keyword? slots) '()))) + `(make-class + ;; evaluate super class variables + (list ,@supers) + ;; evaluate slot definitions, except the slot name! + (list ,@(make-slot-definition-forms slots)) + ;; evaluate class options + ,@options))) + +(define-syntax define-class-pre-definition + (lambda (x) + (syntax-case x () + ((_ (k arg rest ...) out ...) + (keyword? (syntax->datum (syntax k))) + (case (syntax->datum (syntax k)) + ((#:getter #:setter) + (syntax + (define-class-pre-definition (rest ...) + out ... + (if (or (not (defined? 'arg)) + (not (is-a? arg ))) + (toplevel-define! + 'arg + (ensure-generic (if (defined? 'arg) arg #f) 'arg)))))) + ((#:accessor) + (syntax + (define-class-pre-definition (rest ...) + out ... + (if (or (not (defined? 'arg)) + (not (is-a? arg ))) + (toplevel-define! + 'arg + (ensure-accessor (if (defined? 'arg) arg #f) 'arg)))))) + (else + (syntax + (define-class-pre-definition (rest ...) out ...))))) + ((_ () out ...) + (syntax (begin out ...)))))) + +;; Some slot options require extra definitions to be made. In +;; particular, we want to make sure that the generic function objects +;; which represent accessors exist before `make-class' tries to add +;; methods to them. +(define-syntax define-class-pre-definitions + (lambda (x) + (syntax-case x () + ((_ () out ...) + (syntax (begin out ...))) + ((_ (slot rest ...) out ...) + (keyword? (syntax->datum (syntax slot))) + (syntax (begin out ...))) + ((_ (slot rest ...) out ...) + (identifier? (syntax slot)) + (syntax (define-class-pre-definitions (rest ...) + out ...))) + ((_ ((slotname slotopt ...) rest ...) out ...) + (syntax (define-class-pre-definitions (rest ...) + out ... (define-class-pre-definition (slotopt ...)))))))) + +(define-syntax define-class + (syntax-rules () + ((_ name supers slot ...) + (begin + (define-class-pre-definitions (slot ...)) + (if (and (defined? 'name) + (is-a? name ) + (memq (class-precedence-list name))) + (class-redefinition name + (class supers slot ... #:name 'name)) + (toplevel-define! 'name (class supers slot ... #:name 'name))))))) + +(define-syntax standard-define-class + (syntax-rules () + ((_ arg ...) (define-class arg ...)))) + ;;; ;;; {Generic functions and accessors} ;;; @@ -363,13 +391,13 @@ (else (make #:name name))))) ;; same semantics as -(define-macro (define-accessor name) - (if (not (symbol? name)) - (goops-error "bad accessor name: ~S" name)) - `(define ,name - (if (and (defined? ',name) (is-a? ,name )) - (make #:name ',name) - (ensure-accessor (if (defined? ',name) ,name #f) ',name)))) +(define-syntax define-accessor + (syntax-rules () + ((_ name) + (define name + (cond ((not (defined? 'name)) (ensure-accessor #f 'name)) + ((is-a? name ) (make #:name 'name)) + (else (ensure-accessor name 'name))))))) (define (make-setter-name name) (string->symbol (string-append "setter:" (symbol->string name)))) @@ -424,78 +452,132 @@ ;;; {Methods} ;;; -(define-macro (define-method head . body) - (if (not (pair? head)) - (goops-error "bad method head: ~S" head)) - (let ((gf (car head))) - (cond ((and (pair? gf) - (eq? (car gf) 'setter) - (pair? (cdr gf)) - (symbol? (cadr gf)) - (null? (cddr gf))) - ;; named setter method - (let ((name (cadr gf))) - (cond ((not (symbol? name)) - `(add-method! (setter ,name) - (method ,(cdr head) ,@body))) - (else - `(begin - (if (or (not (defined? ',name)) - (not (is-a? ,name ))) - (define-accessor ,name)) - (add-method! (setter ,name) - (method ,(cdr head) ,@body))))))) - ((not (symbol? gf)) - `(add-method! ,gf (method ,(cdr head) ,@body))) - (else - `(begin - ;; FIXME: this code is how it always was, but it's quite - ;; cracky: it will only define the generic function if it - ;; was undefined before (ok), or *was defined to #f*. The - ;; latter is crack. But there are bootstrap issues about - ;; fixing this -- change it to (is-a? ,gf ) and - ;; see. - (if (or (not (defined? ',gf)) - (not ,gf)) - (define-generic ,gf)) - (add-method! ,gf - (method ,(cdr head) ,@body))))))) +(define (toplevel-define! name val) + (module-define! (current-module) name val)) -(define-macro (method args . body) - (letrec ((specializers - (lambda (ls) - (cond ((null? ls) (list (list 'quote '()))) - ((pair? ls) (cons (if (pair? (car ls)) - (cadar ls) - ') - (specializers (cdr ls)))) - (else '())))) - (formals - (lambda (ls) - (if (pair? ls) - (cons (if (pair? (car ls)) (caar ls) (car ls)) - (formals (cdr ls))) - ls)))) - (let ((make-proc (compile-make-procedure (formals args) - (specializers args) - body))) - `(make - #:specializers (cons* ,@(specializers args)) - #:formals ',(formals args) - #:body ',body - #:make-procedure ,make-proc - #:procedure ,(and (not make-proc) - ;; that is to say: we set #:procedure if - ;; `compile-make-procedure' returned `#f', - ;; which is the case if `body' does not - ;; contain a call to `next-method' - `(lambda ,(formals args) - ,@(if (null? body) - ;; This used to be '((begin)), but - ;; guile's memoizer doesn't like - ;; (lambda args (begin)). - '((if #f #f)) - body))))))) +(define-syntax define-method + (syntax-rules (setter) + ((_ ((setter name) . args) body ...) + (begin + (if (or (not (defined? 'name)) + (not (is-a? name ))) + (toplevel-define! 'name + (ensure-accessor + (if (defined? 'name) name #f) 'name))) + (add-method! (setter name) (method args body ...)))) + ((_ (name . args) body ...) + (begin + ;; FIXME: this code is how it always was, but it's quite cracky: + ;; it will only define the generic function if it was undefined + ;; before (ok), or *was defined to #f*. The latter is crack. But + ;; there are bootstrap issues about fixing this -- change it to + ;; (is-a? name ) and see. + (if (or (not (defined? 'name)) + (not name)) + (toplevel-define! 'name (make #:name 'name))) + (add-method! name (method args body ...)))))) + +(define-syntax method + (lambda (x) + (define (parse-args args) + (let lp ((ls args) (formals '()) (specializers '())) + (syntax-case ls () + (((f s) . rest) + (and (identifier? (syntax f)) (identifier? (syntax s))) + (lp (syntax rest) + (cons (syntax f) formals) + (cons (syntax s) specializers))) + ((f . rest) + (identifier? (syntax f)) + (lp (syntax rest) + (cons (syntax f) formals) + (cons (syntax ) specializers))) + (() + (list (reverse formals) + (reverse (cons (syntax '()) specializers)))) + (tail + (identifier? (syntax tail)) + (list (append (reverse formals) (syntax tail)) + (reverse (cons (syntax ) specializers))))))) + + (define (find-free-id exp referent) + (syntax-case exp () + ((x . y) + (or (find-free-id (syntax x) referent) + (find-free-id (syntax y) referent))) + (x + (identifier? (syntax x)) + (let ((id (datum->syntax (syntax x) referent))) + (and (free-identifier=? (syntax x) id) id))) + (_ #f))) + + (define (compute-procedure formals body) + (syntax-case body () + ((body0 ...) + (with-syntax ((formals formals)) + (syntax (lambda formals body0 ...)))))) + + (define (->proper args) + (let lp ((ls args) (out '())) + (syntax-case ls () + ((x . xs) (lp (syntax xs) (cons (syntax x) out))) + (() (reverse out)) + (tail (reverse (cons (syntax tail) out)))))) + + (define (compute-make-procedure formals body next-method) + (syntax-case body () + ((body ...) + (with-syntax ((next-method next-method)) + (syntax-case formals () + ((formal ...) + (syntax + (lambda (real-next-method) + (lambda (formal ...) + (let ((next-method (lambda args + (if (null? args) + (real-next-method formal ...) + (apply real-next-method args))))) + body ...))))) + (formals + (with-syntax (((formal ...) (->proper (syntax formals)))) + (syntax + (lambda (real-next-method) + (lambda formals + (let ((next-method (lambda args + (if (null? args) + (apply real-next-method formal ...) + (apply real-next-method args))))) + body ...))))))))))) + + (define (compute-procedures formals body) + ;; So, our use of this is broken, because it operates on the + ;; pre-expansion source code. It's equivalent to just searching + ;; for referent in the datums. Ah well. + (let ((id (find-free-id body 'next-method))) + (if id + ;; return a make-procedure + (values (syntax #f) + (compute-make-procedure formals body id)) + (values (compute-procedure formals body) + (syntax #f))))) + + (syntax-case x () + ((_ args) (syntax (method args (if #f #f)))) + ((_ args body0 body1 ...) + (with-syntax (((formals (specializer ...)) (parse-args (syntax args)))) + (call-with-values + (lambda () + (compute-procedures (syntax formals) (syntax (body0 body1 ...)))) + (lambda (procedure make-procedure) + (with-syntax ((procedure procedure) + (make-procedure make-procedure)) + (syntax + (make + #:specializers (cons* specializer ...) + #:formals 'formals + #:body '(body0 body1 ...) + #:make-procedure make-procedure + #:procedure procedure)))))))))) ;;; ;;; {add-method!} @@ -1046,27 +1128,9 @@ ;; lookup. Also, @slot-ref and @slot-set! have their own bytecodes. (eval-when (compile) - (use-modules ((language scheme compile-ghil) :select (define-scheme-translator)) - ((language ghil) :select (make-ghil-inline make-ghil-call)) - (system base pmatch)) - - ;; unfortunately, can't use define-inline because these are primitive - ;; syntaxen. - (define-scheme-translator @slot-ref - ((,obj ,index) (guard (integer? index) - (>= index 0) (< index max-fixnum)) - (make-ghil-inline #f #f 'slot-ref - (list (retrans obj) (retrans index)))) - (else - (make-ghil-call e l (retrans (car exp)) (map retrans (cdr exp))))) - - (define-scheme-translator @slot-set! - ((,obj ,index ,val) (guard (integer? index) - (>= index 0) (< index max-fixnum)) - (make-ghil-inline #f #f 'slot-set - (list (retrans obj) (retrans index) (retrans val)))) - (else - (make-ghil-call e l (retrans (car exp)) (map retrans (cdr exp)))))) + (use-modules ((language tree-il primitives) :select (add-interesting-primitive!))) + (add-interesting-primitive! '@slot-ref) + (add-interesting-primitive! '@slot-set!)) (eval-when (eval load compile) (define num-standard-pre-cache 20)) diff --git a/module/oop/goops/Makefile.am b/module/oop/goops/Makefile.am deleted file mode 100644 index 0c90ac49f..000000000 --- a/module/oop/goops/Makefile.am +++ /dev/null @@ -1,30 +0,0 @@ -## Process this file with automake to produce Makefile.in. -## -## Copyright (C) 2000, 2001, 2004, 2005, 2006 Free Software Foundation, Inc. -## -## This file is part of GUILE. -## -## GUILE 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, or -## (at your option) any later version. -## -## GUILE 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 GUILE; see the file COPYING. If not, write -## to the Free Software Foundation, Inc., 51 Franklin Street, Fifth -## Floor, Boston, MA 02110-1301 USA - -AUTOMAKE_OPTIONS = gnu - -modpath = oop/goops -SOURCES = \ - active-slot.scm compile.scm composite-slot.scm describe.scm \ - dispatch.scm internal.scm save.scm stklos.scm util.scm \ - accessors.scm simple.scm - -include $(top_srcdir)/am/guilec diff --git a/module/oop/goops/accessors.scm b/module/oop/goops/accessors.scm index a7baa5c62..5b05d3b15 100644 --- a/module/oop/goops/accessors.scm +++ b/module/oop/goops/accessors.scm @@ -1,19 +1,18 @@ ;;;; Copyright (C) 1999, 2000, 2005, 2006 Free Software Foundation, Inc. ;;;; -;;;; 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 2, or (at your option) -;;;; any later version. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. ;;;; -;;;; This program is distributed in the hope that it will be useful, +;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;;; GNU General Public License for more details. +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. ;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this software; see the file COPYING. If not, write to -;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;;; Boston, MA 02110-1301 USA +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;;;; diff --git a/module/oop/goops/active-slot.scm b/module/oop/goops/active-slot.scm index e6b409ad0..5cd2afe10 100644 --- a/module/oop/goops/active-slot.scm +++ b/module/oop/goops/active-slot.scm @@ -5,7 +5,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/module/oop/goops/compile.scm b/module/oop/goops/compile.scm index 3962be4bc..5db406cd0 100644 --- a/module/oop/goops/compile.scm +++ b/module/oop/goops/compile.scm @@ -3,7 +3,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -24,7 +24,7 @@ (define-module (oop goops compile) :use-module (oop goops) :use-module (oop goops util) - :export (compute-cmethod compile-make-procedure) + :export (compute-cmethod) :no-backtrace ) @@ -34,11 +34,12 @@ (define code-table-lookup (letrec ((check-entry (lambda (entry types) - (if (null? types) - (and (not (struct? (car entry))) - entry) - (and (eq? (car entry) (car types)) - (check-entry (cdr entry) (cdr types))))))) + (cond + ((not (pair? entry)) (and (null? types) entry)) + ((null? types) #f) + (else + (and (eq? (car entry) (car types)) + (check-entry (cdr entry) (cdr types)))))))) (lambda (code-table types) (cond ((null? code-table) #f) ((check-entry (car code-table) types)) @@ -60,9 +61,7 @@ ;;; So, for the reader: there basic idea is that, given that the ;;; semantics of `next-method' depend on the concrete types being ;;; dispatched, why not compile a specific procedure to handle each type -;;; combination that we see at runtime. There are two compilation -;;; strategies implemented: one for the memoizer, and one for the VM -;;; compiler. +;;; combination that we see at runtime. ;;; ;;; In theory we can do much better than a bytecode compilation, because ;;; we know the *exact* types of the arguments. It's ideal for native @@ -71,32 +70,6 @@ ;;; I think this whole generic application mess would benefit from a ;;; strict MOP. -;;; Temporary solution---return #f if x doesn't refer to `next-method'. -(define (next-method? x) - (and (pair? x) - (or (eq? (car x) 'next-method) - (next-method? (car x)) - (next-method? (cdr x))))) - -;; Called by the `method' macro in goops.scm. -(define (compile-make-procedure formals specializers body) - (and (next-method? body) - (let ((next-method-sym (gensym " next-method")) - (args-sym (gensym))) - `(lambda (,next-method-sym) - (lambda ,formals - (let ((next-method (lambda ,args-sym - (if (null? ,args-sym) - ,(if (list? formals) - `(,next-method-sym ,@formals) - `(apply - ,next-method-sym - ,@(improper->proper formals))) - (apply ,next-method-sym ,args-sym))))) - ,@(if (null? body) - '((begin)) - body))))))) - (define (compile-method methods types) (let ((make-procedure (slot-ref (car methods) 'make-procedure))) (if make-procedure diff --git a/module/oop/goops/composite-slot.scm b/module/oop/goops/composite-slot.scm index 9bf5cf8f8..b3f8cc038 100644 --- a/module/oop/goops/composite-slot.scm +++ b/module/oop/goops/composite-slot.scm @@ -5,7 +5,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/module/oop/goops/describe.scm b/module/oop/goops/describe.scm index 184fef214..fa7bc466c 100644 --- a/module/oop/goops/describe.scm +++ b/module/oop/goops/describe.scm @@ -5,7 +5,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/module/oop/goops/dispatch.scm b/module/oop/goops/dispatch.scm index a54044729..0dd169d59 100644 --- a/module/oop/goops/dispatch.scm +++ b/module/oop/goops/dispatch.scm @@ -3,7 +3,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -209,9 +209,8 @@ ;;; ;; Backward compatibility -(if (not (defined? 'lookup-create-cmethod)) - (define (lookup-create-cmethod gf args) - (no-applicable-method (car args) (cadr args)))) +(define (lookup-create-cmethod gf args) + (no-applicable-method (car args) (cadr args))) (define (memoize-method! gf args exp) (if (not (slot-ref gf 'used-by)) diff --git a/module/oop/goops/internal.scm b/module/oop/goops/internal.scm index d996805e4..15919d44b 100644 --- a/module/oop/goops/internal.scm +++ b/module/oop/goops/internal.scm @@ -5,7 +5,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/module/oop/goops/save.scm b/module/oop/goops/save.scm index 4d64da8bb..0c7d71a2d 100644 --- a/module/oop/goops/save.scm +++ b/module/oop/goops/save.scm @@ -5,7 +5,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -110,9 +110,7 @@ ;;; Readables ;;; -(if (or (not (defined? 'readables)) - (not readables)) - (define readables (make-weak-key-hash-table 61))) +(define readables (make-weak-key-hash-table 61)) (define-macro (readable exp) `(make-readable ,exp ',(copy-tree exp))) diff --git a/module/oop/goops/simple.scm b/module/oop/goops/simple.scm index 48e76f312..bc5405a8d 100644 --- a/module/oop/goops/simple.scm +++ b/module/oop/goops/simple.scm @@ -5,7 +5,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -23,6 +23,9 @@ :export (define-class) :no-backtrace) -(define define-class define-class-with-accessors-keywords) +(define-syntax define-class + (syntax-rules () + ((_ arg ...) + (define-class-with-accessors-keywords arg ...)))) (module-use! %module-public-interface (resolve-interface '(oop goops))) diff --git a/module/oop/goops/stklos.scm b/module/oop/goops/stklos.scm index 60ab293c3..835969f13 100644 --- a/module/oop/goops/stklos.scm +++ b/module/oop/goops/stklos.scm @@ -3,7 +3,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -47,51 +47,30 @@ ;;; Enable keyword support (*fixme*---currently this has global effect) (read-set! keywords 'prefix) -(define standard-define-class-transformer - (macro-transformer standard-define-class)) +(define-syntax define-class + (syntax-rules () + ((_ name supers (slot ...) rest ...) + (standard-define-class name supers slot ... rest ...)))) -(define define-class - ;; Syntax - (let ((name cadr) - (supers caddr) - (slots cadddr) - (rest cddddr)) - (procedure->memoizing-macro - (lambda (exp env) - (standard-define-class-transformer - `(define-class ,(name exp) ,(supers exp) ,@(slots exp) - ,@(rest exp)) - env))))) +(define (toplevel-define! name val) + (module-define! (current-module) name val)) -(define define-method - (procedure->memoizing-macro - (lambda (exp env) - (let ((name (cadr exp))) - (if (and (pair? name) - (eq? (car name) 'setter) - (pair? (cdr name)) - (null? (cddr name))) - (let ((name (cadr name))) - (cond ((not (symbol? name)) - (goops-error "bad method name: ~S" name)) - ((defined? name env) - `(begin - (if (not (is-a? ,name )) - (define-accessor ,name)) - (add-method! (setter ,name) (method ,@(cddr exp))))) - (else - `(begin - (define-accessor ,name) - (add-method! (setter ,name) (method ,@(cddr exp))))))) - (cond ((not (symbol? name)) - (goops-error "bad method name: ~S" name)) - ((defined? name env) - `(begin - (if (not (or (is-a? ,name ) - (is-a? ,name ))) - (define-generic ,name)) - (add-method! ,name (method ,@(cddr exp))))) - (else - `(begin - (define-generic ,name) - (add-method! ,name (method ,@(cddr exp))))))))))) +(define-syntax define-method + (syntax-rules (setter) + ((_ (setter name) rest ...) + (begin + (if (or (not (defined? 'name)) + (not (is-a? name ))) + (toplevel-define! 'name + (ensure-accessor + (if (defined? 'name) name #f) 'name))) + (add-method! (setter name) (method rest ...)))) + ((_ name rest ...) + (begin + (if (or (not (defined? 'name)) + (not (or (is-a? name ) + (is-a? name )))) + (toplevel-define! 'name + (ensure-generic + (if (defined? 'name) name #f) 'name))) + (add-method! name (method rest ...)))))) diff --git a/module/oop/goops/util.scm b/module/oop/goops/util.scm index b6276aa37..69bb898bf 100644 --- a/module/oop/goops/util.scm +++ b/module/oop/goops/util.scm @@ -3,7 +3,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/module/rnrs/bytevector.scm b/module/rnrs/bytevector.scm new file mode 100644 index 000000000..32929c698 --- /dev/null +++ b/module/rnrs/bytevector.scm @@ -0,0 +1,85 @@ +;;;; bytevector.scm --- R6RS bytevector API + +;;;; Copyright (C) 2009 Free Software Foundation, Inc. +;;;; +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +;;; Author: Ludovic Courtès + +;;; Commentary: +;;; +;;; A "bytevector" is a raw bit string. This module provides procedures to +;;; manipulate bytevectors and interpret their contents in a number of ways: +;;; bytevector contents can be accessed as signed or unsigned integer of +;;; various sizes and endianness, as IEEE-754 floating point numbers, or as +;;; strings. It is a useful tool to decode binary data. +;;; +;;; Code: + +(define-module (rnrs bytevector) + :export-syntax (endianness) + :export (native-endianness bytevector? + make-bytevector bytevector-length bytevector=? bytevector-fill! + bytevector-copy! bytevector-copy + uniform-array->bytevector + bytevector-u8-ref bytevector-s8-ref + bytevector-u8-set! bytevector-s8-set! bytevector->u8-list + u8-list->bytevector + bytevector-uint-ref bytevector-uint-set! + bytevector-sint-ref bytevector-sint-set! + bytevector->sint-list bytevector->uint-list + uint-list->bytevector sint-list->bytevector + + bytevector-u16-ref bytevector-s16-ref + bytevector-u16-set! bytevector-s16-set! + bytevector-u16-native-ref bytevector-s16-native-ref + bytevector-u16-native-set! bytevector-s16-native-set! + + bytevector-u32-ref bytevector-s32-ref + bytevector-u32-set! bytevector-s32-set! + bytevector-u32-native-ref bytevector-s32-native-ref + bytevector-u32-native-set! bytevector-s32-native-set! + + bytevector-u64-ref bytevector-s64-ref + bytevector-u64-set! bytevector-s64-set! + bytevector-u64-native-ref bytevector-s64-native-ref + bytevector-u64-native-set! bytevector-s64-native-set! + + bytevector-ieee-single-ref + bytevector-ieee-single-set! + bytevector-ieee-single-native-ref + bytevector-ieee-single-native-set! + + bytevector-ieee-double-ref + bytevector-ieee-double-set! + bytevector-ieee-double-native-ref + bytevector-ieee-double-native-set! + + string->utf8 string->utf16 string->utf32 + utf8->string utf16->string utf32->string)) + + +(load-extension "libguile" "scm_init_bytevectors") + +(define-macro (endianness sym) + (if (memq sym '(big little)) + `(quote ,sym) + (error "unsupported endianness" sym))) + +;;; Local Variables: +;;; coding: latin-1 +;;; End: + +;;; bytevector.scm ends here diff --git a/module/rnrs/io/ports.scm b/module/rnrs/io/ports.scm new file mode 100644 index 000000000..d1b96b31a --- /dev/null +++ b/module/rnrs/io/ports.scm @@ -0,0 +1,111 @@ +;;;; ports.scm --- R6RS port API + +;;;; Copyright (C) 2009 Free Software Foundation, Inc. +;;;; +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +;;; Author: Ludovic Courtès + +;;; Commentary: +;;; +;;; The I/O port API of the R6RS is provided by this module. In many areas +;;; it complements or refines Guile's own historical port API. For instance, +;;; it allows for binary I/O with bytevectors. +;;; +;;; Code: + +(define-module (rnrs io ports) + :re-export (eof-object? port? input-port? output-port?) + :export (eof-object + + ;; input & output ports + port-transcoder binary-port? transcoded-port + port-position set-port-position! + port-has-port-position? port-has-set-port-position!? + call-with-port + + ;; input ports + open-bytevector-input-port + make-custom-binary-input-port + + ;; binary input + get-u8 lookahead-u8 + get-bytevector-n get-bytevector-n! + get-bytevector-some get-bytevector-all + + ;; output ports + open-bytevector-output-port + make-custom-binary-output-port + + ;; binary output + put-u8 put-bytevector)) + +(load-extension "libguile" "scm_init_r6rs_ports") + + + +;;; +;;; Input and output ports. +;;; + +(define (port-transcoder port) + (error "port transcoders are not supported" port)) + +(define (binary-port? port) + ;; So far, we don't support transcoders other than the binary transcoder. + #t) + +(define (transcoded-port port) + (error "port transcoders are not supported" port)) + +(define (port-position port) + "Return the offset (an integer) indicating where the next octet will be +read from/written to in @var{port}." + + ;; FIXME: We should raise an `&assertion' error when not supported. + (seek port 0 SEEK_CUR)) + +(define (set-port-position! port offset) + "Set the position where the next octet will be read from/written to +@var{port}." + + ;; FIXME: We should raise an `&assertion' error when not supported. + (seek port offset SEEK_SET)) + +(define (port-has-port-position? port) + "Return @code{#t} is @var{port} supports @code{port-position}." + (and (false-if-exception (port-position port)) #t)) + +(define (port-has-set-port-position!? port) + "Return @code{#t} is @var{port} supports @code{set-port-position!}." + (and (false-if-exception (set-port-position! port (port-position port))) + #t)) + +(define (call-with-port port proc) + "Call @var{proc}, passing it @var{port} and closing @var{port} upon exit of +@var{proc}. Return the return values of @var{proc}." + (dynamic-wind + (lambda () + #t) + (lambda () + (proc port)) + (lambda () + (close-port port)))) + +;;; Local Variables: +;;; coding: latin-1 +;;; End: + +;;; ports.scm ends here diff --git a/scripts/ChangeLog-2008 b/module/scripts/ChangeLog-2008 similarity index 100% rename from scripts/ChangeLog-2008 rename to module/scripts/ChangeLog-2008 diff --git a/scripts/PROGRAM b/module/scripts/PROGRAM.scm old mode 100755 new mode 100644 similarity index 50% rename from scripts/PROGRAM rename to module/scripts/PROGRAM.scm index e83540851..56e5cf334 --- a/scripts/PROGRAM +++ b/module/scripts/PROGRAM.scm @@ -1,26 +1,21 @@ -#!/bin/sh -# aside from this initial boilerplate, this is actually -*- scheme -*- code -main='(module-ref (resolve-module '\''(scripts PROGRAM)) '\'main')' -exec ${GUILE-guile} -l $0 -c "(apply $main (cdr (command-line)))" "$@" -!# ;;; PROGRAM --- Does something ;; Copyright (C) 2002, 2006 Free Software Foundation, Inc. ;; ;; 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 2, or +;; modify it under the terms of the GNU Lesser General Public License +;; as published by the Free Software Foundation; either version 3, 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. +;; Lesser General Public License for more details. ;; -;; You should have received a copy of the GNU General Public License -;; along with this software; see the file COPYING. If not, write to -;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;; Boston, MA 02110-1301 USA +;; You should have received a copy of the GNU Lesser General Public +;; License along with this software; see the file COPYING.LESSER. If +;; not, write to the Free Software Foundation, Inc., 51 Franklin +;; Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Author: J.R.Hacker diff --git a/scripts/README b/module/scripts/README similarity index 100% rename from scripts/README rename to module/scripts/README diff --git a/scripts/api-diff b/module/scripts/api-diff.scm old mode 100755 new mode 100644 similarity index 91% rename from scripts/api-diff rename to module/scripts/api-diff.scm index 0b41eeaaf..b842b03ff --- a/scripts/api-diff +++ b/module/scripts/api-diff.scm @@ -1,26 +1,21 @@ -#!/bin/sh -# aside from this initial boilerplate, this is actually -*- scheme -*- code -main='(module-ref (resolve-module '\''(scripts api-diff)) '\'main')' -exec ${GUILE-guile} -l $0 -c "(apply $main (cdr (command-line)))" "$@" -!# ;;; api-diff --- diff guile-api.alist files ;; Copyright (C) 2002, 2006 Free Software Foundation, Inc. ;; ;; 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 2, or +;; modify it under the terms of the GNU Lesser General Public License +;; as published by the Free Software Foundation; either version 3, 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. +;; Lesser General Public License for more details. ;; -;; You should have received a copy of the GNU General Public License -;; along with this software; see the file COPYING. If not, write to -;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;; Boston, MA 02110-1301 USA +;; You should have received a copy of the GNU Lesser General Public +;; License along with this software; see the file COPYING.LESSER. If +;; not, write to the Free Software Foundation, Inc., 51 Franklin +;; Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Author: Thien-Thi Nguyen diff --git a/scripts/autofrisk b/module/scripts/autofrisk.scm old mode 100755 new mode 100644 similarity index 91% rename from scripts/autofrisk rename to module/scripts/autofrisk.scm index 154b635bb..e29ccc992 --- a/scripts/autofrisk +++ b/module/scripts/autofrisk.scm @@ -1,26 +1,21 @@ -#!/bin/sh -# aside from this initial boilerplate, this is actually -*- scheme -*- code -main='(module-ref (resolve-module '\''(scripts autofrisk)) '\'main')' -exec ${GUILE-guile} -l $0 -c "(apply $main (cdr (command-line)))" "$@" -!# ;;; autofrisk --- Generate module checks for use with auto* tools ;; Copyright (C) 2002, 2006 Free Software Foundation, Inc. ;; ;; 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 2, or +;; modify it under the terms of the GNU Lesser General Public License +;; as published by the Free Software Foundation; either version 3, 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. +;; Lesser General Public License for more details. ;; -;; You should have received a copy of the GNU General Public License -;; along with this software; see the file COPYING. If not, write to -;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;; Boston, MA 02110-1301 USA +;; You should have received a copy of the GNU Lesser General Public +;; License along with this software; see the file COPYING.LESSER. If +;; not, write to the Free Software Foundation, Inc., 51 Franklin +;; Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Author: Thien-Thi Nguyen diff --git a/module/scripts/compile.scm b/module/scripts/compile.scm new file mode 100644 index 000000000..9b14f2fca --- /dev/null +++ b/module/scripts/compile.scm @@ -0,0 +1,183 @@ +;;; Compile --- Command-line Guile Scheme compiler + +;; Copyright 2005,2008,2009 Free Software Foundation, Inc. +;; +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU Lesser General Public License +;; as published by the Free Software Foundation; either version 3, 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 +;; Lesser General Public License for more details. +;; +;; You should have received a copy of the GNU Lesser General Public +;; License along with this software; see the file COPYING.LESSER. If +;; not, write to the Free Software Foundation, Inc., 51 Franklin +;; Street, Fifth Floor, Boston, MA 02110-1301 USA + +;;; Author: Ludovic Courtès +;;; Author: Andy Wingo + +;;; Commentary: + +;; Usage: compile [ARGS] +;; +;; A command-line interface to the Guile compiler. + +;;; Code: + +(define-module (scripts compile) + #:use-module ((system base compile) #:select (compile-file)) + #:use-module (system base message) + #:use-module (srfi srfi-1) + #:use-module (srfi srfi-13) + #:use-module (srfi srfi-37) + #:use-module (ice-9 format) + #:export (compile)) + + +(define (fail . messages) + (format (current-error-port) + (string-concatenate `("error: " ,@messages "~%"))) + (exit 1)) + +(define %options + ;; Specifications of the command-line options. + (list (option '(#\h "help") #f #f + (lambda (opt name arg result) + (alist-cons 'help? #t result))) + (option '("version") #f #f + (lambda (opt name arg result) + (show-version) + (exit 0))) + + (option '(#\L "load-path") #t #f + (lambda (opt name arg result) + (let ((load-path (assoc-ref result 'load-path))) + (alist-cons 'load-path (cons arg load-path) + result)))) + (option '(#\o "output") #t #f + (lambda (opt name arg result) + (if (assoc-ref result 'output-file) + (fail "`-o' option cannot be specified more than once") + (alist-cons 'output-file arg result)))) + + (option '(#\W "warn") #t #f + (lambda (opt name arg result) + (if (string=? arg "help") + (begin + (show-warning-help) + (exit 0)) + (let ((warnings (assoc-ref result 'warnings))) + (alist-cons 'warnings + (cons (string->symbol arg) warnings) + (alist-delete 'warnings result)))))) + + (option '(#\O "optimize") #f #f + (lambda (opt name arg result) + (alist-cons 'optimize? #t result))) + (option '(#\f "from") #t #f + (lambda (opt name arg result) + (if (assoc-ref result 'from) + (fail "`--from' option cannot be specified more than once") + (alist-cons 'from (string->symbol arg) result)))) + (option '(#\t "to") #t #f + (lambda (opt name arg result) + (if (assoc-ref result 'to) + (fail "`--to' option cannot be specified more than once") + (alist-cons 'to (string->symbol arg) result)))))) + +(define (parse-args args) + "Parse argument list @var{args} and return an alist with all the relevant +options." + (args-fold args %options + (lambda (opt name arg result) + (format (current-error-port) "~A: unrecognized option" name) + (exit 1)) + (lambda (file result) + (let ((input-files (assoc-ref result 'input-files))) + (alist-cons 'input-files (cons file input-files) + result))) + + ;; default option values + '((input-files) + (load-path) + (warnings unsupported-warning)))) + +(define (show-version) + (format #t "compile (GNU Guile) ~A~%" (version)) + (format #t "Copyright (C) 2009 Free Software Foundation, Inc. +License LGPLv3+: GNU LGPL version 3 or later . +This is free software: you are free to change and redistribute it. +There is NO WARRANTY, to the extent permitted by law.~%")) + +(define (show-warning-help) + (format #t "The available warning types are:~%~%") + (for-each (lambda (wt) + (format #t " ~22A ~A~%" + (format #f "`~A'" (warning-type-name wt)) + (warning-type-description wt))) + %warning-types) + (format #t "~%")) + + +(define (compile . args) + (let* ((options (parse-args args)) + (help? (assoc-ref options 'help?)) + (compile-opts (let ((o `(#:warnings + ,(assoc-ref options 'warnings)))) + (if (assoc-ref options 'optimize?) + (cons #:O o) + o))) + (from (or (assoc-ref options 'from) 'scheme)) + (to (or (assoc-ref options 'to) 'objcode)) + (input-files (assoc-ref options 'input-files)) + (output-file (assoc-ref options 'output-file)) + (load-path (assoc-ref options 'load-path))) + (if (or help? (null? input-files)) + (begin + (format #t "Usage: compile [OPTION] FILE... +Compile each Guile source file FILE into a Guile object. + + -h, --help print this help message + + -L, --load-path=DIR add DIR to the front of the module load path + -o, --output=OFILE write output to OFILE + + -W, --warn=WARNING emit warnings of type WARNING; use `--warn=help' + for a list of available warnings + + -f, --from=LANG specify a source language other than `scheme' + -t, --to=LANG specify a target language other than `objcode' + +Note that autocompilation will be turned off. + +Report bugs to <~A>.~%" + %guile-bug-report-address) + (exit 0))) + + (set! %load-path (append load-path %load-path)) + (set! %load-should-autocompile #f) + + (if (and output-file + (or (null? input-files) + (not (null? (cdr input-files))))) + (fail "`-o' option can only be specified " + "when compiling a single file")) + + (for-each (lambda (file) + (format #t "wrote `~A'\n" + (compile-file file + #:output-file output-file + #:from from + #:to to + #:opts compile-opts))) + input-files))) + +(define main compile) + +;;; Local Variables: +;;; coding: latin-1 +;;; End: diff --git a/module/scripts/disassemble.scm b/module/scripts/disassemble.scm new file mode 100644 index 000000000..8907f6d08 --- /dev/null +++ b/module/scripts/disassemble.scm @@ -0,0 +1,40 @@ +;;; Disassemble --- Disassemble .go files into something human-readable + +;; Copyright 2005, 2008, 2009 Free Software Foundation, Inc. +;; +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU Lesser General Public License +;; as published by the Free Software Foundation; either version 3, 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 +;; Lesser General Public License for more details. +;; +;; You should have received a copy of the GNU Lesser General Public +;; License along with this software; see the file COPYING.LESSER. If +;; not, write to the Free Software Foundation, Inc., 51 Franklin +;; Street, Fifth Floor, Boston, MA 02110-1301 USA + +;;; Author: Ludovic Courtès +;;; Author: Andy Wingo + +;;; Commentary: + +;; Usage: disassemble [ARGS] + +;;; Code: + +(define-module (scripts disassemble) + #:use-module (system vm objcode) + #:use-module ((language assembly disassemble) + #:renamer (symbol-prefix-proc 'asm:)) + #:export (disassemble)) + +(define (disassemble . files) + (for-each (lambda (file) + (asm:disassemble (load-objcode file))) + files)) + +(define main disassemble) diff --git a/scripts/display-commentary b/module/scripts/display-commentary.scm old mode 100755 new mode 100644 similarity index 74% rename from scripts/display-commentary rename to module/scripts/display-commentary.scm index a12dae8c7..5bd249ce9 --- a/scripts/display-commentary +++ b/module/scripts/display-commentary.scm @@ -1,26 +1,21 @@ -#!/bin/sh -# aside from this initial boilerplate, this is actually -*- scheme -*- code -main='(module-ref (resolve-module '\''(scripts display-commentary)) '\'main')' -exec ${GUILE-guile} -l $0 -c "(apply $main (cdr (command-line)))" "$@" -!# ;;; display-commentary --- As advertized ;; Copyright (C) 2001, 2006 Free Software Foundation, Inc. ;; ;; 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 2, or +;; modify it under the terms of the GNU Lesser General Public License +;; as published by the Free Software Foundation; either version 3, 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. +;; Lesser General Public License for more details. ;; -;; You should have received a copy of the GNU General Public License -;; along with this software; see the file COPYING. If not, write to -;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;; Boston, MA 02110-1301 USA +;; You should have received a copy of the GNU Lesser General Public +;; License along with this software; see the file COPYING.LESSER. If +;; not, write to the Free Software Foundation, Inc., 51 Franklin +;; Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Author: Thien-Thi Nguyen diff --git a/scripts/doc-snarf b/module/scripts/doc-snarf.scm old mode 100755 new mode 100644 similarity index 95% rename from scripts/doc-snarf rename to module/scripts/doc-snarf.scm index 4bc09f57c..b5665b973 --- a/scripts/doc-snarf +++ b/module/scripts/doc-snarf.scm @@ -1,26 +1,21 @@ -#!/bin/sh -# aside from this initial boilerplate, this is actually -*- scheme -*- code -main='(module-ref (resolve-module '\''(scripts doc-snarf)) '\'main')' -exec ${GUILE-guile} -l $0 -c "(apply $main (cdr (command-line)))" "$@" -!# ;;; doc-snarf --- Extract documentation from source files ;; Copyright (C) 2001, 2006 Free Software Foundation, Inc. ;; ;; 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 2, or +;; modify it under the terms of the GNU Lesser General Public License +;; as published by the Free Software Foundation; either version 3, 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. +;; Lesser General Public License for more details. ;; -;; You should have received a copy of the GNU General Public License -;; along with this software; see the file COPYING. If not, write to -;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;; Boston, MA 02110-1301 USA +;; You should have received a copy of the GNU Lesser General Public +;; License along with this software; see the file COPYING.LESSER. If +;; not, write to the Free Software Foundation, Inc., 51 Franklin +;; Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Author: Martin Grabmueller diff --git a/scripts/frisk b/module/scripts/frisk.scm old mode 100755 new mode 100644 similarity index 94% rename from scripts/frisk rename to module/scripts/frisk.scm index 609a5e6a9..0cf50d6a8 --- a/scripts/frisk +++ b/module/scripts/frisk.scm @@ -1,26 +1,21 @@ -#!/bin/sh -# aside from this initial boilerplate, this is actually -*- scheme -*- code -main='(module-ref (resolve-module '\''(scripts frisk)) '\'main')' -exec ${GUILE-guile} -l $0 -c "(apply $main (cdr (command-line)))" "$@" -!# ;;; frisk --- Grok the module interfaces of a body of files ;; Copyright (C) 2002, 2006 Free Software Foundation, Inc. ;; ;; 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 2, or +;; modify it under the terms of the GNU Lesser General Public License +;; as published by the Free Software Foundation; either version 3, 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. +;; Lesser General Public License for more details. ;; -;; You should have received a copy of the GNU General Public License -;; along with this software; see the file COPYING. If not, write to -;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;; Boston, MA 02110-1301 USA +;; You should have received a copy of the GNU Lesser General Public +;; License along with this software; see the file COPYING.LESSER. If +;; not, write to the Free Software Foundation, Inc., 51 Franklin +;; Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Author: Thien-Thi Nguyen diff --git a/scripts/generate-autoload b/module/scripts/generate-autoload.scm old mode 100755 new mode 100644 similarity index 89% rename from scripts/generate-autoload rename to module/scripts/generate-autoload.scm index b08be8357..781931015 --- a/scripts/generate-autoload +++ b/module/scripts/generate-autoload.scm @@ -1,26 +1,21 @@ -#!/bin/sh -# aside from this initial boilerplate, this is actually -*- scheme -*- code -main='(module-ref (resolve-module '\''(scripts generate-autoload)) '\'main')' -exec ${GUILE-guile} -l $0 -c "(apply $main (cdr (command-line)))" "$@" -!# ;;; generate-autoload --- Display define-module form with autoload info ;; Copyright (C) 2001, 2006 Free Software Foundation, Inc. ;; ;; 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 2, or +;; modify it under the terms of the GNU Lesser General Public License +;; as published by the Free Software Foundation; either version 3, 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. +;; Lesser General Public License for more details. ;; -;; You should have received a copy of the GNU General Public License -;; along with this software; see the file COPYING. If not, write to -;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;; Boston, MA 02110-1301 USA +;; You should have received a copy of the GNU Lesser General Public +;; License along with this software; see the file COPYING.LESSER. If +;; not, write to the Free Software Foundation, Inc., 51 Franklin +;; Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Author: Thien-Thi Nguyen diff --git a/scripts/lint b/module/scripts/lint.scm old mode 100755 new mode 100644 similarity index 93% rename from scripts/lint rename to module/scripts/lint.scm index 354420751..b4a7f530a --- a/scripts/lint +++ b/module/scripts/lint.scm @@ -1,26 +1,21 @@ -#!/bin/sh -# aside from this initial boilerplate, this is actually -*- scheme -*- code -main='(module-ref (resolve-module '\''(scripts lint)) '\'main')' -exec ${GUILE-guile} -l $0 -c "(apply $main (cdr (command-line)))" "$@" -!# ;;; lint --- Preemptive checks for coding errors in Guile Scheme code ;; Copyright (C) 2002, 2006 Free Software Foundation, Inc. ;; ;; 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 2, or +;; modify it under the terms of the GNU Lesser General Public License +;; as published by the Free Software Foundation; either version 3, 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. +;; Lesser General Public License for more details. ;; -;; You should have received a copy of the GNU General Public License -;; along with this software; see the file COPYING. If not, write to -;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;; Boston, MA 02110-1301 USA +;; You should have received a copy of the GNU Lesser General Public +;; License along with this software; see the file COPYING.LESSER. If +;; not, write to the Free Software Foundation, Inc., 51 Franklin +;; Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Author: Neil Jerram diff --git a/scripts/punify b/module/scripts/punify.scm old mode 100755 new mode 100644 similarity index 78% rename from scripts/punify rename to module/scripts/punify.scm index 0f6a36114..1627722d3 --- a/scripts/punify +++ b/module/scripts/punify.scm @@ -1,26 +1,21 @@ -#!/bin/sh -# aside from this initial boilerplate, this is actually -*- scheme -*- code -main='(module-ref (resolve-module '\''(scripts punify)) '\'main')' -exec ${GUILE-guile} -l $0 -c "(apply $main (cdr (command-line)))" "$@" -!# ;;; punify --- Display Scheme code w/o unnecessary comments / whitespace ;; Copyright (C) 2001, 2006 Free Software Foundation, Inc. ;; ;; 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 2, or +;; modify it under the terms of the GNU Lesser General Public License +;; as published by the Free Software Foundation; either version 3, 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. +;; Lesser General Public License for more details. ;; -;; You should have received a copy of the GNU General Public License -;; along with this software; see the file COPYING. If not, write to -;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;; Boston, MA 02110-1301 USA +;; You should have received a copy of the GNU Lesser General Public +;; License along with this software; see the file COPYING.LESSER. If +;; not, write to the Free Software Foundation, Inc., 51 Franklin +;; Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Author: Thien-Thi Nguyen diff --git a/scripts/read-rfc822 b/module/scripts/read-rfc822.scm old mode 100755 new mode 100644 similarity index 87% rename from scripts/read-rfc822 rename to module/scripts/read-rfc822.scm index 0904d61d1..c0a54f28c --- a/scripts/read-rfc822 +++ b/module/scripts/read-rfc822.scm @@ -1,26 +1,21 @@ -#!/bin/sh -# aside from this initial boilerplate, this is actually -*- scheme -*- code -main='(module-ref (resolve-module '\''(scripts read-rfc822)) '\'main')' -exec ${GUILE-guile} -l $0 -c "(apply $main (cdr (command-line)))" "$@" -!# ;;; read-rfc822 --- Validate RFC822 file by displaying it to stdout ;; Copyright (C) 2002, 2004, 2006 Free Software Foundation, Inc. ;; ;; 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 2, or +;; modify it under the terms of the GNU Lesser General Public License +;; as published by the Free Software Foundation; either version 3, 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. +;; Lesser General Public License for more details. ;; -;; You should have received a copy of the GNU General Public License -;; along with this software; see the file COPYING. If not, write to -;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;; Boston, MA 02110-1301 USA +;; You should have received a copy of the GNU Lesser General Public +;; License along with this software; see the file COPYING.LESSER. If +;; not, write to the Free Software Foundation, Inc., 51 Franklin +;; Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Author: Thien-Thi Nguyen diff --git a/scripts/read-scheme-source b/module/scripts/read-scheme-source.scm old mode 100755 new mode 100644 similarity index 94% rename from scripts/read-scheme-source rename to module/scripts/read-scheme-source.scm index 05bb1064c..b48a88f9b --- a/scripts/read-scheme-source +++ b/module/scripts/read-scheme-source.scm @@ -1,26 +1,21 @@ -#!/bin/sh -# aside from this initial boilerplate, this is actually -*- scheme -*- code -main='(module-ref (resolve-module '\''(scripts read-scheme-source)) '\'main')' -exec ${GUILE-guile} -l $0 -c "(apply $main (cdr (command-line)))" "$@" -!# ;;; read-scheme-source --- Read a file, recognizing scheme forms and comments ;; Copyright (C) 2001, 2006 Free Software Foundation, Inc. ;; ;; 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 2, or +;; modify it under the terms of the GNU Lesser General Public License +;; as published by the Free Software Foundation; either version 3, 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. +;; Lesser General Public License for more details. ;; -;; You should have received a copy of the GNU General Public License -;; along with this software; see the file COPYING. If not, write to -;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;; Boston, MA 02110-1301 USA +;; You should have received a copy of the GNU Lesser General Public +;; License along with this software; see the file COPYING.LESSER. If +;; not, write to the Free Software Foundation, Inc., 51 Franklin +;; Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Author: Thien-Thi Nguyen diff --git a/scripts/read-text-outline b/module/scripts/read-text-outline.scm old mode 100755 new mode 100644 similarity index 93% rename from scripts/read-text-outline rename to module/scripts/read-text-outline.scm index c85026952..64221fbe1 --- a/scripts/read-text-outline +++ b/module/scripts/read-text-outline.scm @@ -1,26 +1,21 @@ -#!/bin/sh -# aside from this initial boilerplate, this is actually -*- scheme -*- code -main='(module-ref (resolve-module '\''(scripts read-text-outline)) '\'main')' -exec ${GUILE-guile} -l $0 -c "(apply $main (cdr (command-line)))" "$@" -!# ;;; read-text-outline --- Read a text outline and display it as a sexp ;; Copyright (C) 2002, 2006 Free Software Foundation, Inc. ;; ;; 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 2, or +;; modify it under the terms of the GNU Lesser General Public License +;; as published by the Free Software Foundation; either version 3, 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. +;; Lesser General Public License for more details. ;; -;; You should have received a copy of the GNU General Public License -;; along with this software; see the file COPYING. If not, write to -;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;; Boston, MA 02110-1301 USA +;; You should have received a copy of the GNU Lesser General Public +;; License along with this software; see the file COPYING.LESSER. If +;; not, write to the Free Software Foundation, Inc., 51 Franklin +;; Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Author: Thien-Thi Nguyen diff --git a/scripts/scan-api b/module/scripts/scan-api.scm old mode 100755 new mode 100644 similarity index 92% rename from scripts/scan-api rename to module/scripts/scan-api.scm index 3ea10dbe6..9236f8742 --- a/scripts/scan-api +++ b/module/scripts/scan-api.scm @@ -1,26 +1,21 @@ -#!/bin/sh -# aside from this initial boilerplate, this is actually -*- scheme -*- code -main='(module-ref (resolve-module '\''(scripts scan-api)) '\'main')' -exec ${GUILE-guile} -l $0 -c "(apply $main (cdr (command-line)))" "$@" -!# ;;; scan-api --- Scan and group interpreter and libguile interface elements ;; Copyright (C) 2002, 2006 Free Software Foundation, Inc. ;; ;; 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 2, or +;; modify it under the terms of the GNU Lesser General Public License +;; as published by the Free Software Foundation; either version 3, 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. +;; Lesser General Public License for more details. ;; -;; You should have received a copy of the GNU General Public License -;; along with this software; see the file COPYING. If not, write to -;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;; Boston, MA 02110-1301 USA +;; You should have received a copy of the GNU Lesser General Public +;; License along with this software; see the file COPYING.LESSER. If +;; not, write to the Free Software Foundation, Inc., 51 Franklin +;; Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Author: Thien-Thi Nguyen diff --git a/scripts/snarf-check-and-output-texi b/module/scripts/snarf-check-and-output-texi.scm old mode 100755 new mode 100644 similarity index 93% rename from scripts/snarf-check-and-output-texi rename to module/scripts/snarf-check-and-output-texi.scm index ea33e1797..0e7efae47 --- a/scripts/snarf-check-and-output-texi +++ b/module/scripts/snarf-check-and-output-texi.scm @@ -1,26 +1,21 @@ -#!/bin/sh -# aside from this initial boilerplate, this is actually -*- scheme -*- code -main="(module-ref (resolve-module '(scripts snarf-check-and-output-texi)) 'main)" -exec ${GUILE-guile} -l $0 -c "(apply $main (cdr (command-line)))" "$@" -!# ;;; snarf-check-and-output-texi --- called by the doc snarfer. ;; Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc. ;; ;; 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 2, or +;; modify it under the terms of the GNU Lesser General Public License +;; as published by the Free Software Foundation; either version 3, 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. +;; Lesser General Public License for more details. ;; -;; You should have received a copy of the GNU General Public License -;; along with this software; see the file COPYING. If not, write to -;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;; Boston, MA 02110-1301 USA +;; You should have received a copy of the GNU Lesser General Public +;; License along with this software; see the file COPYING.LESSER. If +;; not, write to the Free Software Foundation, Inc., 51 Franklin +;; Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Author: Michael Livshin diff --git a/scripts/snarf-guile-m4-docs b/module/scripts/snarf-guile-m4-docs.scm old mode 100755 new mode 100644 similarity index 78% rename from scripts/snarf-guile-m4-docs rename to module/scripts/snarf-guile-m4-docs.scm index b80f187fe..05c305ebd --- a/scripts/snarf-guile-m4-docs +++ b/module/scripts/snarf-guile-m4-docs.scm @@ -1,26 +1,21 @@ -#!/bin/sh -# aside from this initial boilerplate, this is actually -*- scheme -*- code -main='(module-ref (resolve-module '\''(scripts snarf-guile-m4-docs)) '\'main')' -exec ${GUILE-guile} -l $0 -c "(apply $main (cdr (command-line)))" "$@" -!# ;;; snarf-guile-m4-docs --- Parse guile.m4 comments for texi documentation ;; Copyright (C) 2002, 2006 Free Software Foundation, Inc. ;; ;; 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 2, or +;; modify it under the terms of the GNU Lesser General Public License +;; as published by the Free Software Foundation; either version 3, 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. +;; Lesser General Public License for more details. ;; -;; You should have received a copy of the GNU General Public License -;; along with this software; see the file COPYING. If not, write to -;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;; Boston, MA 02110-1301 USA +;; You should have received a copy of the GNU Lesser General Public +;; License along with this software; see the file COPYING.LESSER. If +;; not, write to the Free Software Foundation, Inc., 51 Franklin +;; Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Author: Thien-Thi Nguyen diff --git a/scripts/summarize-guile-TODO b/module/scripts/summarize-guile-TODO.scm old mode 100755 new mode 100644 similarity index 92% rename from scripts/summarize-guile-TODO rename to module/scripts/summarize-guile-TODO.scm index 79543fe27..a67c92ede --- a/scripts/summarize-guile-TODO +++ b/module/scripts/summarize-guile-TODO.scm @@ -1,26 +1,21 @@ -#!/bin/sh -# aside from this initial boilerplate, this is actually -*- scheme -*- code -main='(module-ref (resolve-module '\''(scripts summarize-guile-TODO)) '\'main')' -exec ${GUILE-guile} -l $0 -c "(apply $main (cdr (command-line)))" "$@" -!# ;;; summarize-guile-TODO --- Display Guile TODO list in various ways ;; Copyright (C) 2002, 2006 Free Software Foundation, Inc. ;; ;; 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 2, or +;; modify it under the terms of the GNU Lesser General Public License +;; as published by the Free Software Foundation; either version 3, 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. +;; Lesser General Public License for more details. ;; -;; You should have received a copy of the GNU General Public License -;; along with this software; see the file COPYING. If not, write to -;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;; Boston, MA 02110-1301 USA +;; You should have received a copy of the GNU Lesser General Public +;; License along with this software; see the file COPYING.LESSER. If +;; not, write to the Free Software Foundation, Inc., 51 Franklin +;; Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Author: Thien-Thi Nguyen diff --git a/scripts/use2dot b/module/scripts/use2dot.scm old mode 100755 new mode 100644 similarity index 84% rename from scripts/use2dot rename to module/scripts/use2dot.scm index 30b4690e0..ab97afbc7 --- a/scripts/use2dot +++ b/module/scripts/use2dot.scm @@ -1,26 +1,21 @@ -#!/bin/sh -# aside from this initial boilerplate, this is actually -*- scheme -*- code -main='(module-ref (resolve-module '\''(scripts use2dot)) '\'main')' -exec ${GUILE-guile} -l $0 -c "(apply $main (cdr (command-line)))" "$@" -!# ;;; use2dot --- Display module dependencies as a DOT specification ;; Copyright (C) 2001, 2006 Free Software Foundation, Inc. ;; ;; 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 2, or +;; modify it under the terms of the GNU Lesser General Public License +;; as published by the Free Software Foundation; either version 3, 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. +;; Lesser General Public License for more details. ;; -;; You should have received a copy of the GNU General Public License -;; along with this software; see the file COPYING. If not, write to -;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;; Boston, MA 02110-1301 USA +;; You should have received a copy of the GNU Lesser General Public +;; License along with this software; see the file COPYING.LESSER. If +;; not, write to the Free Software Foundation, Inc., 51 Franklin +;; Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Author: Thien-Thi Nguyen diff --git a/module/srfi/Makefile.am b/module/srfi/Makefile.am index 0fc926e40..7cbac6630 100644 --- a/module/srfi/Makefile.am +++ b/module/srfi/Makefile.am @@ -4,20 +4,20 @@ ## ## This file is part of GUILE. ## -## GUILE 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, or +## GUILE is free software; you can redistribute it and/or modify it +## under the terms of the GNU Lesser General Public License as +## published by the Free Software Foundation; either version 3, or ## (at your option) any later version. -## +## ## GUILE 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 GUILE; see the file COPYING. If not, write -## to the Free Software Foundation, Inc., 51 Franklin Street, Fifth -## Floor, Boston, MA 02110-1301 USA +## GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with GUILE; see the file COPYING.LESSER. If not, +## write to the Free Software Foundation, Inc., 51 Franklin Street, +## Fifth Floor, Boston, MA 02110-1301 USA AUTOMAKE_OPTIONS = gnu diff --git a/module/srfi/srfi-1.scm b/module/srfi/srfi-1.scm index 7c55d9923..db21122b9 100644 --- a/module/srfi/srfi-1.scm +++ b/module/srfi/srfi-1.scm @@ -5,7 +5,7 @@ ;; This library is free software; you can redistribute it and/or ;; modify it under the terms of the GNU Lesser General Public ;; License as published by the Free Software Foundation; either -;; version 2.1 of the License, or (at your option) any later version. +;; version 3 of the License, or (at your option) any later version. ;; ;; This library is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/module/srfi/srfi-10.scm b/module/srfi/srfi-10.scm index 8e7181a3b..533d9f769 100644 --- a/module/srfi/srfi-10.scm +++ b/module/srfi/srfi-10.scm @@ -5,7 +5,7 @@ ;; This library is free software; you can redistribute it and/or ;; modify it under the terms of the GNU Lesser General Public ;; License as published by the Free Software Foundation; either -;; version 2.1 of the License, or (at your option) any later version. +;; version 3 of the License, or (at your option) any later version. ;; ;; This library is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/module/srfi/srfi-11.scm b/module/srfi/srfi-11.scm index 9e17d6632..22bda21a2 100644 --- a/module/srfi/srfi-11.scm +++ b/module/srfi/srfi-11.scm @@ -1,11 +1,11 @@ ;;; srfi-11.scm --- let-values and let*-values -;; Copyright (C) 2000, 2001, 2002, 2004, 2006 Free Software Foundation, Inc. +;; Copyright (C) 2000, 2001, 2002, 2004, 2006, 2009 Free Software Foundation, Inc. ;; ;; This library is free software; you can redistribute it and/or ;; modify it under the terms of the GNU Lesser General Public ;; License as published by the Free Software Foundation; either -;; version 2.1 of the License, or (at your option) any later version. +;; version 3 of the License, or (at your option) any later version. ;; ;; This library is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -37,7 +37,6 @@ ;;; Code: (define-module (srfi srfi-11) - :use-module (ice-9 syncase) :export-syntax (let-values let*-values)) (cond-expand-provide (current-module) '(srfi-11)) @@ -64,148 +63,58 @@ ;; (q )) ;; (baz x y z p q)))))) -;; I originally wrote this as a define-macro, but then I found out -;; that guile's gensym/gentemp was broken, so I tried rewriting it as -;; a syntax-rules statement. -;; [make-symbol now fixes gensym/gentemp problems.] -;; -;; Since syntax-rules didn't seem powerful enough to implement -;; let-values in one definition without exposing illegal syntax (or -;; perhaps my brain's just not powerful enough :>). I tried writing -;; it using a private helper, but that didn't work because the -;; let-values expands outside the scope of this module. I wonder why -;; syntax-rules wasn't designed to allow "private" patterns or -;; similar... -;; -;; So in the end, I dumped the syntax-rules implementation, reproduced -;; here for posterity, and went with the define-macro one below -- -;; gensym/gentemp's got to be fixed anyhow... -; -; (define-syntax let-values-helper -; (syntax-rules () -; ;; Take the vars from one let binding (i.e. the (x y z) from ((x y -; ;; z) (values 1 2 3)) and turn it in to the corresponding (lambda -; ;; ( ) ...) from above, keeping track of the -; ;; temps you create so you can use them later... -; ;; -; ;; I really don't fully understand why the (var-1 var-1) trick -; ;; works below, but basically, when all those (x x) bindings show -; ;; up in the final "let", syntax-rules forces a renaming. - -; ((_ "consumer" () lambda-tmps final-let-bindings lv-bindings -; body ...) -; (lambda lambda-tmps -; (let-values-helper "cwv" lv-bindings final-let-bindings body ...))) - -; ((_ "consumer" (var-1 var-2 ...) (lambda-tmp ...) final-let-bindings lv-bindings -; body ...) -; (let-values-helper "consumer" -; (var-2 ...) -; (lambda-tmp ... var-1) -; ((var-1 var-1) . final-let-bindings) -; lv-bindings -; body ...)) - -; ((_ "cwv" () final-let-bindings body ...) -; (let final-let-bindings -; body ...)) - -; ((_ "cwv" ((vars-1 binding-1) other-bindings ...) final-let-bindings -; body ...) -; (call-with-values (lambda () binding-1) -; (let-values-helper "consumer" -; vars-1 -; () -; final-let-bindings -; (other-bindings ...) -; body ...))))) -; -; (define-syntax let-values -; (syntax-rules () -; ((let-values () body ...) -; (begin body ...)) -; ((let-values (binding ...) body ...) -; (let-values-helper "cwv" (binding ...) () body ...)))) -; -; -; (define-syntax let-values -; (letrec-syntax ((build-consumer -; ;; Take the vars from one let binding (i.e. the (x -; ;; y z) from ((x y z) (values 1 2 3)) and turn it -; ;; in to the corresponding (lambda ( -; ;; ) ...) from above. -; (syntax-rules () -; ((_ () new-tmps tmp-vars () body ...) -; (lambda new-tmps -; body ...)) -; ((_ () new-tmps tmp-vars vars body ...) -; (lambda new-tmps -; (lv-builder vars tmp-vars body ...))) -; ((_ (var-1 var-2 ...) new-tmps tmp-vars vars body ...) -; (build-consumer (var-2 ...) -; (tmp-1 . new-tmps) -; ((var-1 tmp-1) . tmp-vars) -; bindings -; body ...)))) -; (lv-builder -; (syntax-rules () -; ((_ () tmp-vars body ...) -; (let tmp-vars -; body ...)) -; ((_ ((vars-1 binding-1) (vars-2 binding-2) ...) -; tmp-vars -; body ...) -; (call-with-values (lambda () binding-1) -; (build-consumer vars-1 -; () -; tmp-vars -; ((vars-2 binding-2) ...) -; body ...)))))) -; -; (syntax-rules () -; ((_ () body ...) -; (begin body ...)) -; ((_ ((vars binding) ...) body ...) -; (lv-builder ((vars binding) ...) () body ...))))) - -(define-macro (let-values vars . body) - - (define (map-1-dot proc elts) - ;; map over one optionally dotted (a b c . d) list, producing an - ;; optionally dotted result. - (cond - ((null? elts) '()) - ((pair? elts) (cons (proc (car elts)) (map-1-dot proc (cdr elts)))) - (else (proc elts)))) - - (define (undot-list lst) - ;; produce a non-dotted list from a possibly dotted list. - (cond - ((null? lst) '()) - ((pair? lst) (cons (car lst) (undot-list (cdr lst)))) - (else (list lst)))) - - (define (let-values-helper vars body prev-let-vars) - (let* ((var-binding (car vars)) - (new-tmps (map-1-dot (lambda (sym) (make-symbol "let-values-var")) - (car var-binding))) - (let-vars (map (lambda (sym tmp) (list sym tmp)) - (undot-list (car var-binding)) - (undot-list new-tmps)))) - - (if (null? (cdr vars)) - `(call-with-values (lambda () ,(cadr var-binding)) - (lambda ,new-tmps - (let ,(apply append let-vars prev-let-vars) - ,@body))) - `(call-with-values (lambda () ,(cadr var-binding)) - (lambda ,new-tmps - ,(let-values-helper (cdr vars) body - (cons let-vars prev-let-vars))))))) - - (if (null? vars) - `(begin ,@body) - (let-values-helper vars body '()))) +;; We could really use quasisyntax here... +(define-syntax let-values + (lambda (x) + (syntax-case x () + ((_ ((binds exp)) b0 b1 ...) + (syntax (call-with-values (lambda () exp) + (lambda binds b0 b1 ...)))) + ((_ (clause ...) b0 b1 ...) + (let lp ((clauses (syntax (clause ...))) + (ids '()) + (tmps '())) + (if (null? clauses) + (with-syntax (((id ...) ids) + ((tmp ...) tmps)) + (syntax (let ((id tmp) ...) + b0 b1 ...))) + (syntax-case (car clauses) () + (((var ...) exp) + (with-syntax (((new-tmp ...) (generate-temporaries + (syntax (var ...)))) + ((id ...) ids) + ((tmp ...) tmps)) + (with-syntax ((inner (lp (cdr clauses) + (syntax (var ... id ...)) + (syntax (new-tmp ... tmp ...))))) + (syntax (call-with-values (lambda () exp) + (lambda (new-tmp ...) inner)))))) + ((vars exp) + (with-syntax ((((new-tmp . new-var) ...) + (let lp ((vars (syntax vars))) + (syntax-case vars () + ((id . rest) + (acons (syntax id) + (car + (generate-temporaries (syntax (id)))) + (lp (syntax rest)))) + (id (acons (syntax id) + (car + (generate-temporaries (syntax (id)))) + '()))))) + ((id ...) ids) + ((tmp ...) tmps)) + (with-syntax ((inner (lp (cdr clauses) + (syntax (new-var ... id ...)) + (syntax (new-tmp ... tmp ...)))) + (args (let lp ((tmps (syntax (new-tmp ...)))) + (syntax-case tmps () + ((id) (syntax id)) + ((id . rest) (cons (syntax id) + (lp (syntax rest)))))))) + (syntax (call-with-values (lambda () exp) + (lambda args inner))))))))))))) ;;;;;;;;;;;;;; ;; let*-values @@ -227,28 +136,11 @@ (define-syntax let*-values (syntax-rules () ((let*-values () body ...) - (begin body ...)) + (let () body ...)) ((let*-values ((vars-1 binding-1) (vars-2 binding-2) ...) body ...) (call-with-values (lambda () binding-1) (lambda vars-1 (let*-values ((vars-2 binding-2) ...) body ...)))))) -; Alternate define-macro implementation... -; -; (define-macro (let*-values vars . body) -; (define (let-values-helper vars body) -; (let ((var-binding (car vars))) -; (if (null? (cdr vars)) -; `(call-with-values (lambda () ,(cadr var-binding)) -; (lambda ,(car var-binding) -; ,@body)) -; `(call-with-values (lambda () ,(cadr var-binding)) -; (lambda ,(car var-binding) -; ,(let-values-helper (cdr vars) body)))))) - -; (if (null? vars) -; `(begin ,@body) -; (let-values-helper vars body))) - ;;; srfi-11.scm ends here diff --git a/module/srfi/srfi-13.scm b/module/srfi/srfi-13.scm index 1036a0f47..a2d64cba3 100644 --- a/module/srfi/srfi-13.scm +++ b/module/srfi/srfi-13.scm @@ -5,7 +5,7 @@ ;; This library is free software; you can redistribute it and/or ;; modify it under the terms of the GNU Lesser General Public ;; License as published by the Free Software Foundation; either -;; version 2.1 of the License, or (at your option) any later version. +;; version 3 of the License, or (at your option) any later version. ;; ;; This library is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/module/srfi/srfi-14.scm b/module/srfi/srfi-14.scm index 100b43b8e..ecc21e52e 100644 --- a/module/srfi/srfi-14.scm +++ b/module/srfi/srfi-14.scm @@ -5,7 +5,7 @@ ;; This library is free software; you can redistribute it and/or ;; modify it under the terms of the GNU Lesser General Public ;; License as published by the Free Software Foundation; either -;; version 2.1 of the License, or (at your option) any later version. +;; version 3 of the License, or (at your option) any later version. ;; ;; This library is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/module/srfi/srfi-16.scm b/module/srfi/srfi-16.scm index 0b213fde7..dc3c70920 100644 --- a/module/srfi/srfi-16.scm +++ b/module/srfi/srfi-16.scm @@ -5,7 +5,7 @@ ;; This library is free software; you can redistribute it and/or ;; modify it under the terms of the GNU Lesser General Public ;; License as published by the Free Software Foundation; either -;; version 2.1 of the License, or (at your option) any later version. +;; version 3 of the License, or (at your option) any later version. ;; ;; This library is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/module/srfi/srfi-17.scm b/module/srfi/srfi-17.scm index c9cb2abfe..a14c5c33b 100644 --- a/module/srfi/srfi-17.scm +++ b/module/srfi/srfi-17.scm @@ -5,7 +5,7 @@ ;; This library is free software; you can redistribute it and/or ;; modify it under the terms of the GNU Lesser General Public ;; License as published by the Free Software Foundation; either -;; version 2.1 of the License, or (at your option) any later version. +;; version 3 of the License, or (at your option) any later version. ;; ;; This library is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/module/srfi/srfi-18.scm b/module/srfi/srfi-18.scm index 925ecb304..26acb6300 100644 --- a/module/srfi/srfi-18.scm +++ b/module/srfi/srfi-18.scm @@ -5,7 +5,7 @@ ;; This library is free software; you can redistribute it and/or ;; modify it under the terms of the GNU Lesser General Public ;; License as published by the Free Software Foundation; either -;; version 2.1 of the License, or (at your option) any later version. +;; version 3 of the License, or (at your option) any later version. ;; ;; This library is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -151,8 +151,10 @@ (hashq-set! thread-exception-handlers ct hl) (handler obj)) (lambda () - (let ((r (thunk))) - (hashq-set! thread-exception-handlers ct hl) r)))))) + (call-with-values thunk + (lambda res + (hashq-set! thread-exception-handlers ct hl) + (apply values res)))))))) (define (current-exception-handler) (car (current-handler-stack))) @@ -249,8 +251,8 @@ (define (wrap thunk) (lambda (continuation) (with-exception-handler (lambda (obj) - (apply (current-exception-handler) (list obj)) - (apply continuation (list))) + ((current-exception-handler) obj) + (continuation)) thunk))) ;; A pass-thru to cancel-thread that first installs a handler that throws diff --git a/module/srfi/srfi-19.scm b/module/srfi/srfi-19.scm index 29c604fcd..b91824976 100644 --- a/module/srfi/srfi-19.scm +++ b/module/srfi/srfi-19.scm @@ -5,7 +5,7 @@ ;; This library is free software; you can redistribute it and/or ;; modify it under the terms of the GNU Lesser General Public ;; License as published by the Free Software Foundation; either -;; version 2.1 of the License, or (at your option) any later version. +;; version 3 of the License, or (at your option) any later version. ;; ;; This library is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/module/srfi/srfi-2.scm b/module/srfi/srfi-2.scm index 0dfe38305..c09323fbb 100644 --- a/module/srfi/srfi-2.scm +++ b/module/srfi/srfi-2.scm @@ -5,7 +5,7 @@ ;; This library is free software; you can redistribute it and/or ;; modify it under the terms of the GNU Lesser General Public ;; License as published by the Free Software Foundation; either -;; version 2.1 of the License, or (at your option) any later version. +;; version 3 of the License, or (at your option) any later version. ;; ;; This library is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/module/srfi/srfi-26.scm b/module/srfi/srfi-26.scm index 410d2e2f8..324a5dc37 100644 --- a/module/srfi/srfi-26.scm +++ b/module/srfi/srfi-26.scm @@ -5,7 +5,7 @@ ;; This library is free software; you can redistribute it and/or ;; modify it under the terms of the GNU Lesser General Public ;; License as published by the Free Software Foundation; either -;; version 2.1 of the License, or (at your option) any later version. +;; version 3 of the License, or (at your option) any later version. ;; ;; This library is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/module/srfi/srfi-31.scm b/module/srfi/srfi-31.scm index 54c2f9fd4..4238dc269 100644 --- a/module/srfi/srfi-31.scm +++ b/module/srfi/srfi-31.scm @@ -5,7 +5,7 @@ ;; This library is free software; you can redistribute it and/or ;; modify it under the terms of the GNU Lesser General Public ;; License as published by the Free Software Foundation; either -;; version 2.1 of the License, or (at your option) any later version. +;; version 3 of the License, or (at your option) any later version. ;; ;; This library is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/module/srfi/srfi-34.scm b/module/srfi/srfi-34.scm index 18a2fda1c..7fb9d1dd6 100644 --- a/module/srfi/srfi-34.scm +++ b/module/srfi/srfi-34.scm @@ -5,7 +5,7 @@ ;; This library is free software; you can redistribute it and/or ;; modify it under the terms of the GNU Lesser General Public ;; License as published by the Free Software Foundation; either -;; version 2.1 of the License, or (at your option) any later version. +;; version 3 of the License, or (at your option) any later version. ;; ;; This library is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/module/srfi/srfi-35.scm b/module/srfi/srfi-35.scm index 203546625..873b08b13 100644 --- a/module/srfi/srfi-35.scm +++ b/module/srfi/srfi-35.scm @@ -1,11 +1,11 @@ ;;; srfi-35.scm --- Conditions -;; Copyright (C) 2007, 2008 Free Software Foundation, Inc. +;; Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc. ;; ;; This library is free software; you can redistribute it and/or ;; modify it under the terms of the GNU Lesser General Public ;; License as published by the Free Software Foundation; either -;; version 2.1 of the License, or (at your option) any later version. +;; version 3 of the License, or (at your option) any later version. ;; ;; This library is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -28,6 +28,7 @@ (define-module (srfi srfi-35) #:use-module (srfi srfi-1) + #:use-module (ice-9 syncase) #:export (make-condition-type condition-type? make-condition condition? condition-has-type? condition-ref make-compound-condition extract-condition @@ -274,37 +275,39 @@ by C." ;;; Syntax. ;;; -(define-macro (define-condition-type name parent pred . field-specs) - `(begin - (define ,name - (make-condition-type ',name ,parent - ',(map car field-specs))) - (define (,pred c) - (condition-has-type? c ,name)) - ,@(map (lambda (field-spec) - (let ((field-name (car field-spec)) - (accessor (cadr field-spec))) - `(define (,accessor c) - (condition-ref c ',field-name)))) - field-specs))) +(define-syntax define-condition-type + (syntax-rules () + ((_ name parent pred (field-name field-accessor) ...) + (begin + (define name + (make-condition-type 'name parent '(field-name ...))) + (define (pred c) + (condition-has-type? c name)) + (define (field-accessor c) + (condition-ref c 'field-name)) + ...)))) -(define-macro (condition . type-field-bindings) - (cond ((null? type-field-bindings) - (error "`condition' syntax error" type-field-bindings)) - (else - ;; the poor man's hygienic macro - (let ((mc (gensym "mc")) - (mcct (gensym "mcct"))) - `(let ((,mc (@ (srfi srfi-35) make-condition)) - (,mcct (@@ (srfi srfi-35) make-compound-condition-type))) - (,mc (,mcct 'compound (list ,@(map car type-field-bindings))) - ,@(append-map (lambda (type-field-binding) - (append-map (lambda (field+value) - (let ((f (car field+value)) - (v (cadr field+value))) - `(',f ,v))) - (cdr type-field-binding))) - type-field-bindings))))))) +(define-syntax compound-condition + ;; Create a compound condition using `make-compound-condition-type'. + (syntax-rules () + ((_ (type ...) (field ...)) + (condition ((make-compound-condition-type '%compound `(,type ...)) + field ...))))) + +(define-syntax condition-instantiation + ;; Build the `(make-condition type ...)' call. + (syntax-rules () + ((_ type (out ...)) + (make-condition type out ...)) + ((_ type (out ...) (field-name field-value) rest ...) + (condition-instantiation type (out ... 'field-name field-value) rest ...)))) + +(define-syntax condition + (syntax-rules () + ((_ (type field ...)) + (condition-instantiation type () field ...)) + ((_ (type field ...) ...) + (compound-condition (type ...) (field ... ...))))) ;;; diff --git a/module/srfi/srfi-37.scm b/module/srfi/srfi-37.scm index 5e6d512a2..565b44cb9 100644 --- a/module/srfi/srfi-37.scm +++ b/module/srfi/srfi-37.scm @@ -5,7 +5,7 @@ ;; This library is free software; you can redistribute it and/or ;; modify it under the terms of the GNU Lesser General Public ;; License as published by the Free Software Foundation; either -;; version 2.1 of the License, or (at your option) any later version. +;; version 3 of the License, or (at your option) any later version. ;; ;; This library is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/module/srfi/srfi-39.scm b/module/srfi/srfi-39.scm index 086751170..61e67b820 100644 --- a/module/srfi/srfi-39.scm +++ b/module/srfi/srfi-39.scm @@ -5,7 +5,7 @@ ;; This library is free software; you can redistribute it and/or ;; modify it under the terms of the GNU Lesser General Public ;; License as published by the Free Software Foundation; either -;; version 2.1 of the License, or (at your option) any later version. +;; version 3 of the License, or (at your option) any later version. ;; ;; This library is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -35,7 +35,6 @@ ;;; Code: (define-module (srfi srfi-39) - #:use-module (ice-9 syncase) #:use-module (srfi srfi-16) #:export (make-parameter) diff --git a/module/srfi/srfi-4.scm b/module/srfi/srfi-4.scm index f30e83952..b133f2106 100644 --- a/module/srfi/srfi-4.scm +++ b/module/srfi/srfi-4.scm @@ -5,7 +5,7 @@ ;; This library is free software; you can redistribute it and/or ;; modify it under the terms of the GNU Lesser General Public ;; License as published by the Free Software Foundation; either -;; version 2.1 of the License, or (at your option) any later version. +;; version 3 of the License, or (at your option) any later version. ;; ;; This library is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/module/srfi/srfi-6.scm b/module/srfi/srfi-6.scm index 1e455bb5c..098b586cc 100644 --- a/module/srfi/srfi-6.scm +++ b/module/srfi/srfi-6.scm @@ -5,7 +5,7 @@ ;; This library is free software; you can redistribute it and/or ;; modify it under the terms of the GNU Lesser General Public ;; License as published by the Free Software Foundation; either -;; version 2.1 of the License, or (at your option) any later version. +;; version 3 of the License, or (at your option) any later version. ;; ;; This library is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/module/srfi/srfi-60.scm b/module/srfi/srfi-60.scm index 177f97681..c9eb60f8b 100644 --- a/module/srfi/srfi-60.scm +++ b/module/srfi/srfi-60.scm @@ -5,7 +5,7 @@ ;; This library is free software; you can redistribute it and/or ;; modify it under the terms of the GNU Lesser General Public ;; License as published by the Free Software Foundation; either -;; version 2.1 of the License, or (at your option) any later version. +;; version 3 of the License, or (at your option) any later version. ;; ;; This library is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/module/srfi/srfi-69.scm b/module/srfi/srfi-69.scm index d26393576..0d835d09b 100644 --- a/module/srfi/srfi-69.scm +++ b/module/srfi/srfi-69.scm @@ -5,7 +5,7 @@ ;; This library is free software; you can redistribute it and/or ;; modify it under the terms of the GNU Lesser General Public ;; License as published by the Free Software Foundation; either -;; version 2.1 of the License, or (at your option) any later version. +;; version 3 of the License, or (at your option) any later version. ;; ;; This library is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/module/srfi/srfi-8.scm b/module/srfi/srfi-8.scm index c15cbe9c0..ced123894 100644 --- a/module/srfi/srfi-8.scm +++ b/module/srfi/srfi-8.scm @@ -5,7 +5,7 @@ ;; This library is free software; you can redistribute it and/or ;; modify it under the terms of the GNU Lesser General Public ;; License as published by the Free Software Foundation; either -;; version 2.1 of the License, or (at your option) any later version. +;; version 3 of the License, or (at your option) any later version. ;; ;; This library is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/module/srfi/srfi-88.scm b/module/srfi/srfi-88.scm index ebde81d0b..0fec19ee1 100644 --- a/module/srfi/srfi-88.scm +++ b/module/srfi/srfi-88.scm @@ -5,7 +5,7 @@ ;; This library is free software; you can redistribute it and/or ;; modify it under the terms of the GNU Lesser General Public ;; License as published by the Free Software Foundation; either -;; version 2.1 of the License, or (at your option) any later version. +;; version 3 of the License, or (at your option) any later version. ;; ;; This library is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/module/srfi/srfi-9.scm b/module/srfi/srfi-9.scm index 59d23bf53..c64be5e51 100644 --- a/module/srfi/srfi-9.scm +++ b/module/srfi/srfi-9.scm @@ -5,7 +5,7 @@ ;; This library is free software; you can redistribute it and/or ;; modify it under the terms of the GNU Lesser General Public ;; License as published by the Free Software Foundation; either -;; version 2.1 of the License, or (at your option) any later version. +;; version 3 of the License, or (at your option) any later version. ;; ;; This library is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/module/srfi/srfi-98.scm b/module/srfi/srfi-98.scm new file mode 100644 index 000000000..944f40261 --- /dev/null +++ b/module/srfi/srfi-98.scm @@ -0,0 +1,44 @@ +;;; srfi-98.scm --- An interface to access environment variables + +;; Copyright (C) 2009 Free Software Foundation, Inc. +;; +;; This library is free software; you can redistribute it and/or +;; modify it under the terms of the GNU Lesser General Public +;; License as published by the Free Software Foundation; either +;; version 3 of the License, or (at your option) any later version. +;; +;; This library is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; Lesser General Public License for more details. +;; +;; You should have received a copy of the GNU Lesser General Public +;; License along with this library; if not, write to the Free Software +;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +;;; Author: Julian Graham +;;; Date: 2009-05-26 + +;;; Commentary: + +;; This is an implementation of SRFI-98 (An interface to access environment +;; variables). +;; +;; This module is fully documented in the Guile Reference Manual. + +;;; Code: + +(define-module (srfi srfi-98) + :use-module (srfi srfi-1) + :export (get-environment-variable + get-environment-variables)) + +(cond-expand-provide (current-module) '(srfi-98)) + +(define get-environment-variable getenv) +(define (get-environment-variables) + (define (string->alist-entry str) + (let ((pvt (string-index str #\=)) + (len (string-length str))) + (and pvt (cons (substring str 0 pvt) (substring str (+ pvt 1) len))))) + (filter-map string->alist-entry (environ))) diff --git a/module/system/base/compile.scm b/module/system/base/compile.scm index 891902367..8470f39e2 100644 --- a/module/system/base/compile.scm +++ b/module/system/base/compile.scm @@ -2,26 +2,26 @@ ;; Copyright (C) 2001, 2009 Free Software Foundation, Inc. -;; 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 2, 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 COPYING. If not, write to -;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. +;;; This library is free software; you can redistribute it and/or +;;; modify it under the terms of the GNU Lesser General Public +;;; License as published by the Free Software Foundation; either +;;; version 3 of the License, or (at your option) any later version. +;;; +;;; This library is distributed in the hope that it will be useful, +;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;; Lesser General Public License for more details. +;;; +;;; You should have received a copy of the GNU Lesser General Public +;;; License along with this library; if not, write to the Free Software +;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Code: (define-module (system base compile) #:use-module (system base syntax) #:use-module (system base language) + #:use-module (system base message) #:use-module (system vm vm) ;; FIXME: there's a reason for this, can't remember why tho #:use-module (ice-9 regex) #:use-module (ice-9 optargs) @@ -29,7 +29,7 @@ #:export (syntax-error *current-language* compiled-file-name compile-file compile-and-load - compile compile-time-environment + compile decompile) #:export-syntax (call-with-compile-error-catch)) @@ -73,7 +73,7 @@ thunk (lambda () #t)))) -(define (call-with-output-file/atomic filename proc) +(define* (call-with-output-file/atomic filename proc #:optional reference) (let* ((template (string-append filename ".XXXXXX")) (tmp (mkstemp! template))) (call-once @@ -83,6 +83,9 @@ (proc tmp) (chmod tmp (logand #o0666 (lognot (umask)))) (close-port tmp) + (if reference + (let ((st (stat reference))) + (utime template (stat:atime st) (stat:mtime st)))) (rename-file template filename)) (lambda args (delete-file template))))))) @@ -92,90 +95,138 @@ x (lookup-language x))) -(define* (compile-file file #:optional output-file - #:key (to 'objcode) (opts '())) - (let ((comp (or output-file (compiled-file-name file))) - (lang (ensure-language (current-language))) - (to (ensure-language to))) - (catch 'nothing-at-all - (lambda () - (call-with-compile-error-catch - (lambda () - (call-with-output-file/atomic comp - (lambda (port) - (let ((print (language-printer to))) - (print (compile (read-file-in file lang) - #:from lang #:to to #:opts opts) - port)))) - (format #t "wrote `~A'\n" comp)))) - (lambda (key . args) - (format #t "ERROR: during compilation of ~A:\n" file) - (display "ERROR: ") - (apply format #t (cadr args) (caddr args)) - (newline) - (format #t "ERROR: ~A ~A ~A\n" key (car args) (cadddr args)) - (delete-file comp))))) +;; Throws an exception if `dir' is not writable. The double-stat is OK, +;; as this is only used during compilation. +(define (ensure-writable-dir dir) + (if (file-exists? dir) + (if (access? dir W_OK) + #t + (error "directory not writable" dir)) + (begin + (ensure-writable-dir (dirname dir)) + (mkdir dir)))) -(define* (compile-and-load file #:key (to 'value) (opts '())) - (let ((lang (ensure-language (current-language)))) - (compile (read-file-in file lang) #:to 'value #:opts opts))) +(define (dsu-sort list key less) + (map cdr + (stable-sort (map (lambda (x) (cons (key x) x)) list) + (lambda (x y) (less (car x) (car y)))))) +;;; This function is among the trickiest I've ever written. I tried many +;;; variants. In the end, simple is best, of course. +;;; +;;; After turning this around a number of times, it seems that the the +;;; desired behavior is that .go files should exist in a path, for +;;; searching. That is orthogonal to this function. For writing .go +;;; files, either you know where they should go, in which case you tell +;;; compile-file explicitly, as in the srcdir != builddir case; or you +;;; don't know, in which case this function is called, and we just put +;;; them in your own ccache dir in ~/.guile-ccache. (define (compiled-file-name file) - (let ((base (basename file)) - (cext (cond ((or (null? %load-compiled-extensions) - (string-null? (car %load-compiled-extensions))) - (warn "invalid %load-compiled-extensions" - %load-compiled-extensions) - ".go") - (else (car %load-compiled-extensions))))) - (let lp ((exts %load-extensions)) - (cond ((null? exts) (string-append file cext)) - ((string-null? (car exts)) (lp (cdr exts))) - ((string-suffix? (car exts) base) - (string-append - (dirname file) "/" - (substring base 0 - (- (string-length base) (string-length (car exts)))) - cext)) - (else (lp (cdr exts))))))) + (define (compiled-extension) + (cond ((or (null? %load-compiled-extensions) + (string-null? (car %load-compiled-extensions))) + (warn "invalid %load-compiled-extensions" + %load-compiled-extensions) + ".go") + (else (car %load-compiled-extensions)))) + (and %compile-fallback-path + (let ((f (string-append + %compile-fallback-path + ;; no need for '/' separator here, canonicalize-path + ;; will give us an absolute path + (canonicalize-path file) + (compiled-extension)))) + (and (false-if-exception (ensure-writable-dir (dirname f))) + f)))) + +(define* (compile-file file #:key + (output-file #f) + (env #f) + (from (current-language)) + (to 'objcode) + (opts '())) + (let ((comp (or output-file (compiled-file-name file))) + (in (open-input-file file))) + (ensure-writable-dir (dirname comp)) + (call-with-output-file/atomic comp + (lambda (port) + ((language-printer (ensure-language to)) + (read-and-compile in #:env env #:from from #:to to #:opts opts) + port)) + file) + comp)) + +(define* (compile-and-load file #:key (from 'scheme) (to 'value) (opts '())) + (read-and-compile (open-input-file file) + #:from from #:to to #:opts opts)) ;;; ;;; Compiler interface ;;; -(define (read-file-in file lang) - (call-with-input-file file - (or (language-read-file lang) - (error "language has no #:read-file" lang)))) - (define (compile-passes from to opts) (map cdr (or (lookup-compilation-order from to) (error "no way to compile" from "to" to)))) (define (compile-fold passes exp env opts) - (if (null? passes) - exp - (receive (exp env) ((car passes) exp env opts) - (compile-fold (cdr passes) exp env opts)))) + (let lp ((passes passes) (x exp) (e env) (cenv env) (first? #t)) + (if (null? passes) + (values x e cenv) + (receive (x e new-cenv) ((car passes) x e opts) + (lp (cdr passes) x e (if first? new-cenv cenv) #f))))) -(define (compile-time-environment) - "A special function known to the compiler that, when compiled, will -return a representation of the lexical environment in place at compile -time. Useful for supporting some forms of dynamic compilation. Returns -#f if called from the interpreter." - #f) +(define (find-language-joint from to) + (let lp ((in (reverse (or (lookup-compilation-order from to) + (error "no way to compile" from "to" to)))) + (lang to)) + (cond ((null? in) + (error "don't know how to join expressions" from to)) + ((language-joiner lang) lang) + (else + (lp (cdr in) (caar in)))))) + +(define* (read-and-compile port #:key + (env #f) + (from (current-language)) + (to 'objcode) + (opts '())) + (let ((from (ensure-language from)) + (to (ensure-language to))) + (let ((joint (find-language-joint from to))) + (with-fluids ((*current-language* from)) + (let lp ((exps '()) (env #f) (cenv env)) + (let ((x ((language-reader (current-language)) port))) + (cond + ((eof-object? x) + (compile ((language-joiner joint) (reverse exps) env) + #:from joint #:to to #:env env #:opts opts)) + (else + ;; compile-fold instead of compile so we get the env too + (receive (jexp jenv jcenv) + (compile-fold (compile-passes (current-language) joint opts) + x cenv opts) + (lp (cons jexp exps) jenv jcenv)))))))))) (define* (compile x #:key (env #f) (from (current-language)) (to 'value) (opts '())) - (compile-fold (compile-passes from to opts) - x - env - opts)) + + (let ((warnings (memq #:warnings opts))) + (if (pair? warnings) + (let ((warnings (cadr warnings))) + ;; Sanity-check the requested warnings. + (for-each (lambda (w) + (or (lookup-warning-type w) + (warning 'unsupported-warning #f w))) + warnings)))) + + (receive (exp env cenv) + (compile-fold (compile-passes from to opts) x env opts) + exp)) ;;; diff --git a/module/system/base/language.scm b/module/system/base/language.scm index 70000c551..3670c53d9 100644 --- a/module/system/base/language.scm +++ b/module/system/base/language.scm @@ -1,21 +1,21 @@ ;;; Multi-language support -;; Copyright (C) 2001 Free Software Foundation, Inc. +;; Copyright (C) 2001, 2009 Free Software Foundation, Inc. -;; 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 2, or (at your option) -;; any later version. +;; This library is free software; you can redistribute it and/or +;; modify it under the terms of the GNU Lesser General Public +;; License as published by the Free Software Foundation; either +;; version 3 of the License, or (at your option) any later version. ;; -;; This program is distributed in the hope that it will be useful, +;; This library is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; Lesser General Public License for more details. ;; -;; You should have received a copy of the GNU General Public License -;; along with this program; see the file COPYING. If not, write to -;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. +;; You should have received a copy of the GNU Lesser General Public +;; License along with this library; if not, write to the Free Software +;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +;; 02110-1301 USA ;;; Code: @@ -23,8 +23,9 @@ #:use-module (system base syntax) #:export (define-language language? lookup-language make-language language-name language-title language-version language-reader - language-printer language-parser language-read-file + language-printer language-parser language-compilers language-decompilers language-evaluator + language-joiner lookup-compilation-order lookup-decompilation-order invalidate-compilation-cache!)) @@ -41,10 +42,10 @@ reader printer (parser #f) - (read-file #f) (compilers '()) (decompilers '()) - (evaluator #f)) + (evaluator #f) + (joiner #f)) (define-macro (define-language name . spec) `(begin diff --git a/module/system/base/message.scm b/module/system/base/message.scm new file mode 100644 index 000000000..6b68c5639 --- /dev/null +++ b/module/system/base/message.scm @@ -0,0 +1,102 @@ +;;; User interface messages + +;; Copyright (C) 2009 Free Software Foundation, Inc. + +;;; This library is free software; you can redistribute it and/or +;;; modify it under the terms of the GNU Lesser General Public +;;; License as published by the Free Software Foundation; either +;;; version 3 of the License, or (at your option) any later version. +;;; +;;; This library is distributed in the hope that it will be useful, +;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;; Lesser General Public License for more details. +;;; +;;; You should have received a copy of the GNU Lesser General Public +;;; License along with this library; if not, write to the Free Software +;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +;;; Commentary: +;;; +;;; This module provide a simple interface to send messages to the user. +;;; TODO: Internationalize messages. +;;; +;;; Code: + +(define-module (system base message) + #:use-module (srfi srfi-1) + #:use-module (srfi srfi-9) + #:export (*current-warning-port* warning + + warning-type? warning-type-name warning-type-description + warning-type-printer lookup-warning-type + + %warning-types)) + + +;;; +;;; Source location +;;; + +(define (location-string loc) + (if (pair? loc) + (format #f "~a:~a:~a" + (or (assoc-ref loc 'filename) "") + (1+ (assoc-ref loc 'line)) + (assoc-ref loc 'column)) + "")) + + +;;; +;;; Warnings +;;; + +(define *current-warning-port* + ;; The port where warnings are sent. + (make-fluid)) + +(fluid-set! *current-warning-port* (current-error-port)) + +(define-record-type + (make-warning-type name description printer) + warning-type? + (name warning-type-name) + (description warning-type-description) + (printer warning-type-printer)) + +(define %warning-types + ;; List of know warning types. + (map (lambda (args) + (apply make-warning-type args)) + + `((unsupported-warning ;; a "meta warning" + "warn about unknown warning types" + ,(lambda (port unused name) + (format port "warning: unknown warning type `~A'~%" + name))) + + (unused-variable + "report unused variables" + ,(lambda (port loc name) + (format port "~A: warning: unused variable `~A'~%" + loc name)))))) + +(define (lookup-warning-type name) + "Return the warning type NAME or `#f' if not found." + (find (lambda (wt) + (eq? name (warning-type-name wt))) + %warning-types)) + +(define (warning type location . args) + "Emit a warning of type TYPE for source location LOCATION (a source +property alist) using the data in ARGS." + (let ((wt (lookup-warning-type type)) + (port (fluid-ref *current-warning-port*))) + (if (warning-type? wt) + (apply (warning-type-printer wt) + port (location-string location) + args) + (format port "~A: unknown warning type `~A': ~A~%" + (location-string location) type args)))) + +;;; message.scm ends here diff --git a/module/system/base/pmatch.scm b/module/system/base/pmatch.scm index ed61464f0..4777431e5 100644 --- a/module/system/base/pmatch.scm +++ b/module/system/base/pmatch.scm @@ -1,6 +1,5 @@ (define-module (system base pmatch) - #:use-module (ice-9 syncase) - #:export (pmatch ppat)) + #:export (pmatch)) ;; FIXME: shouldn't have to export ppat... ;; Originally written by Oleg Kiselyov. Taken from: @@ -17,15 +16,15 @@ (let ((v (op arg ...))) (pmatch v cs ...))) ((_ v) (if #f #f)) - ((_ v (else e0 e ...)) (begin e0 e ...)) + ((_ v (else e0 e ...)) (let () e0 e ...)) ((_ v (pat (guard g ...) e0 e ...) cs ...) (let ((fk (lambda () (pmatch v cs ...)))) (ppat v pat - (if (and g ...) (begin e0 e ...) (fk)) + (if (and g ...) (let () e0 e ...) (fk)) (fk)))) ((_ v (pat e0 e ...) cs ...) (let ((fk (lambda () (pmatch v cs ...)))) - (ppat v pat (begin e0 e ...) (fk)))))) + (ppat v pat (let () e0 e ...) (fk)))))) (define-syntax ppat (syntax-rules (_ quote unquote) diff --git a/module/system/base/syntax.scm b/module/system/base/syntax.scm index d968bdff8..249961d79 100644 --- a/module/system/base/syntax.scm +++ b/module/system/base/syntax.scm @@ -1,21 +1,20 @@ ;;; Guile VM specific syntaxes and utilities -;; Copyright (C) 2001 Free Software Foundation, Inc +;; Copyright (C) 2001, 2009 Free Software Foundation, Inc -;; 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 2, 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 COPYING. If not, write to -;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA +;;; This library is free software; you can redistribute it and/or +;;; modify it under the terms of the GNU Lesser General Public +;;; License as published by the Free Software Foundation; either +;;; version 3 of the License, or (at your option) any later version. +;;; +;;; This library is distributed in the hope that it will be useful, +;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;; Lesser General Public License for more details. +;;; +;;; You should have received a copy of the GNU Lesser General Public +;;; License along with this library; if not, write to the Free Software +;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Code: @@ -175,29 +174,70 @@ ;; 5.88 0.01 0.01 list-index -(define-macro (record-case record . clauses) - (let ((r (gensym)) - (rtd (gensym))) - (define (process-clause clause) - (if (eq? (car clause) 'else) - clause - (let ((record-type (caar clause)) - (slots (cdar clause)) - (body (cdr clause))) - (let ((stem (trim-brackets record-type))) - `((eq? ,rtd ,record-type) - (let ,(map (lambda (slot) - (if (pair? slot) - `(,(car slot) (,(symbol-append stem '- (cadr slot)) ,r)) - `(,slot (,(symbol-append stem '- slot) ,r)))) - slots) - ,@(if (pair? body) body '((if #f #f))))))))) - `(let* ((,r ,record) - (,rtd (struct-vtable ,r))) - (cond ,@(let ((clauses (map process-clause clauses))) - (if (assq 'else clauses) - clauses - (append clauses `((else (error "unhandled record" ,r)))))))))) +;;; So ugly... but I am too ignorant to know how to make it better. +(define-syntax record-case + (lambda (x) + (syntax-case x () + ((_ record clause ...) + (let ((r (syntax r)) + (rtd (syntax rtd))) + (define (process-clause tag fields exprs) + (let ((infix (trim-brackets (syntax->datum tag)))) + (with-syntax ((tag tag) + (((f . accessor) ...) + (let lp ((fields fields)) + (syntax-case fields () + (() (syntax ())) + (((v0 f0) f1 ...) + (acons (syntax v0) + (datum->syntax x + (symbol-append infix '- (syntax->datum + (syntax f0)))) + (lp (syntax (f1 ...))))) + ((f0 f1 ...) + (acons (syntax f0) + (datum->syntax x + (symbol-append infix '- (syntax->datum + (syntax f0)))) + (lp (syntax (f1 ...)))))))) + ((e0 e1 ...) + (syntax-case exprs () + (() (syntax (#t))) + ((e0 e1 ...) (syntax (e0 e1 ...)))))) + (syntax + ((eq? rtd tag) + (let ((f (accessor r)) + ...) + e0 e1 ...)))))) + (with-syntax + ((r r) + (rtd rtd) + ((processed ...) + (let lp ((clauses (syntax (clause ...))) + (out '())) + (syntax-case clauses (else) + (() + (reverse! (cons (syntax + (else (error "unhandled record" r))) + out))) + (((else e0 e1 ...)) + (reverse! (cons (syntax (else e0 e1 ...)) out))) + (((else e0 e1 ...) . rest) + (syntax-violation 'record-case + "bad else clause placement" + (syntax x) + (syntax (else e0 e1 ...)))) + (((( f0 ...) e0 ...) . rest) + (lp (syntax rest) + (cons (process-clause (syntax ) + (syntax (f0 ...)) + (syntax (e0 ...))) + out))))))) + (syntax + (let* ((r record) + (rtd (struct-vtable r))) + (cond processed ...))))))))) + ;; Here we take the terrorism to another level. Nasty, but the client ;; code looks good. diff --git a/module/system/repl/command.scm b/module/system/repl/command.scm index cf09e01af..a99e1bae9 100644 --- a/module/system/repl/command.scm +++ b/module/system/repl/command.scm @@ -1,33 +1,33 @@ ;;; Repl commands -;; Copyright (C) 2001 Free Software Foundation, Inc. +;; Copyright (C) 2001, 2009 Free Software Foundation, Inc. -;; 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 2, or (at your option) -;; any later version. +;; This library is free software; you can redistribute it and/or +;; modify it under the terms of the GNU Lesser General Public +;; License as published by the Free Software Foundation; either +;; version 3 of the License, or (at your option) any later version. ;; -;; This program is distributed in the hope that it will be useful, +;; This library is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; Lesser General Public License for more details. ;; -;; You should have received a copy of the GNU General Public License -;; along with this program; see the file COPYING. If not, write to -;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. +;; You should have received a copy of the GNU Lesser General Public +;; License along with this library; if not, write to the Free Software +;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +;; 02110-1301 USA ;;; Code: (define-module (system repl command) - #:use-syntax (system base syntax) + #:use-module (system base syntax) #:use-module (system base pmatch) #:use-module (system base compile) #:use-module (system repl common) #:use-module (system vm objcode) #:use-module (system vm program) #:use-module (system vm vm) - #:autoload (system base language) (lookup-language) + #:autoload (system base language) (lookup-language language-reader) #:autoload (system vm debug) (vm-debugger vm-backtrace) #:autoload (system vm trace) (vm-trace vm-trace-on vm-trace-off) #:autoload (system vm profile) (vm-profile) @@ -35,6 +35,7 @@ #:use-module (ice-9 session) #:use-module (ice-9 documentation) #:use-module (ice-9 and-let-star) + #:use-module (ice-9 rdelim) #:export (meta-command)) @@ -109,33 +110,66 @@ (let ((abbrev (if abbrev (format #f "[,~A]" abbrev) ""))) (format #t " ,~24A ~8@A - ~A\n" usage abbrev summary))) -(define (meta-command repl line) - (let ((input (call-with-input-string (string-append "(" line ")") read))) - (if (not (null? input)) - (do ((key (car input)) - (args (cdr input) (cdr args)) - (opts '() (cons (make-keyword-from-dash-symbol (car args)) opts))) - ((or (null? args) - (not (symbol? (car args))) - (not (eq? (string-ref (symbol->string (car args)) 0) #\-))) - (let ((c (lookup-command key))) - (if c - (cond ((memq #:h opts) (display-command c)) - (else (apply (command-procedure c) - repl (append! args (reverse! opts))))) - (user-error "Unknown meta command: ~A" key)))))))) +(define (read-datum repl) + (read)) + +(define read-line + (let ((orig-read-line read-line)) + (lambda (repl) + (orig-read-line)))) + +(define (meta-command repl) + (let ((command (read-datum repl))) + (if (not (symbol? command)) + (user-error "Meta-command not a symbol: ~s" command)) + (let ((c (lookup-command command))) + (if c + ((command-procedure c) repl) + (user-error "Unknown meta command: ~A" command))))) + +(define-syntax define-meta-command + (syntax-rules () + ((_ (name repl (expression0 ...) . datums) docstring b0 b1 ...) + (define (name repl) + docstring + (let* ((expression0 + (with-fluid* current-reader + (language-reader (repl-language repl)) + (lambda () (repl-reader "")))) + ...) + (apply (lambda datums b0 b1 ...) + (let ((port (open-input-string (read-line repl)))) + (let lp ((out '())) + (let ((x (read port))) + (if (eof-object? x) + (reverse out) + (lp (cons x out)))))))))) + ((_ (name repl . datums) docstring b0 b1 ...) + (define-meta-command (name repl () . datums) + docstring b0 b1 ...)))) + ;;; ;;; Help commands ;;; -(define (help repl . args) - "help [GROUP] -List available meta commands. -A command group name can be given as an optional argument. +(define-meta-command (help repl . args) + "help +help GROUP +help [-c] COMMAND + +Gives help on the meta-commands available at the REPL. + +With one argument, tries to look up the argument as a group name, giving +help on that group if successful. Otherwise tries to look up the +argument as a command, giving help on the command. + +If there is a command whose name is also a group name, use the ,help +-c COMMAND form to give help on the command instead of the group. + Without any argument, a list of help commands and command groups -are displayed, as you have already seen ;)" +are displayed." (pmatch args (() (display-group (lookup-group 'help)) @@ -154,23 +188,30 @@ are displayed, as you have already seen ;)" (for-each display-group *command-table*)) ((,group) (guard (lookup-group group)) (display-group (lookup-group group))) + ((,command) (guard (lookup-command command)) + (display-command (lookup-command command))) + ((-c ,command) (guard (lookup-command command)) + (display-command (lookup-command command))) + ((,command) + (user-error "Unknown command or group: ~A" command)) + ((-c ,command) + (user-error "Unknown command: ~A" command)) (else - (user-error "Unknown command group: ~A" (car args))))) + (user-error "Bad arguments: ~A" args)))) (define guile:apropos apropos) -(define (apropos repl regexp) +(define-meta-command (apropos repl regexp) "apropos REGEXP Find bindings/modules/packages." (guile:apropos (->string regexp))) -(define (describe repl obj) +(define-meta-command (describe repl (form)) "describe OBJ Show description/documentation." - (display (object-documentation - (repl-eval repl (repl-parse repl obj)))) + (display (object-documentation (repl-eval repl (repl-parse repl form)))) (newline)) -(define (option repl . args) +(define-meta-command (option repl . args) "option [KEY VALUE] List/show/set options." (pmatch args @@ -190,7 +231,7 @@ List/show/set options." (apply vm-trace-on vm val) (vm-trace-off vm)))))))) -(define (quit repl) +(define-meta-command (quit repl) "quit Quit this session." (throw 'quit)) @@ -200,7 +241,7 @@ Quit this session." ;;; Module commands ;;; -(define (module repl . args) +(define-meta-command (module repl . args) "module [MODULE] Change modules / Show current module." (pmatch args @@ -209,7 +250,7 @@ Change modules / Show current module." (set-current-module (resolve-module mod-name))) (,mod-name (set-current-module (resolve-module mod-name))))) -(define (import repl . args) +(define-meta-command (import repl . args) "import [MODULE ...] Import modules / List those imported." (let () @@ -222,7 +263,7 @@ Import modules / List those imported." (for-each puts (map module-name (module-uses (current-module)))) (for-each use args)))) -(define (load repl file . opts) +(define-meta-command (load repl file . opts) "load FILE Load a file in the current module. @@ -233,7 +274,7 @@ Load a file in the current module. (apply load-file file opts)))) (vm-load (repl-vm repl) objcode))) -(define (binding repl . opts) +(define-meta-command (binding repl) "binding List current bindings." (module-for-each (lambda (k v) (format #t "~23A ~A\n" k v)) @@ -244,7 +285,7 @@ List current bindings." ;;; Language commands ;;; -(define (language repl name) +(define-meta-command (language repl name) "language LANGUAGE Change languages." (set! (repl-language repl) (lookup-language name)) @@ -255,7 +296,7 @@ Change languages." ;;; Compile commands ;;; -(define (compile repl form . opts) +(define-meta-command (compile repl (form) . opts) "compile FORM Generate compiled code. @@ -266,11 +307,11 @@ Generate compiled code. -O Enable optimization -D Add debug information" (let ((x (apply repl-compile repl (repl-parse repl form) opts))) - (cond ((objcode? x) (disassemble-objcode x)) + (cond ((objcode? x) (guile:disassemble x)) (else (repl-print repl x))))) (define guile:compile-file compile-file) -(define (compile-file repl file . opts) +(define-meta-command (compile-file repl file . opts) "compile-file FILE Compile a file." (guile:compile-file (->string file) #:opts opts)) @@ -278,12 +319,12 @@ Compile a file." (define (guile:disassemble x) ((@ (language assembly disassemble) disassemble) x)) -(define (disassemble repl prog) +(define-meta-command (disassemble repl (form)) "disassemble PROGRAM Disassemble a program." - (guile:disassemble (repl-eval repl (repl-parse repl prog)))) + (guile:disassemble (repl-eval repl (repl-parse repl form)))) -(define (disassemble-file repl file) +(define-meta-command (disassemble-file repl file) "disassemble-file FILE Disassemble a file." (guile:disassemble (load-objcode (->string file)))) @@ -293,7 +334,7 @@ Disassemble a file." ;;; Profile commands ;;; -(define (time repl form) +(define-meta-command (time repl (form)) "time FORM Time execution." (let* ((vms-start (vm-stats (repl-vm repl))) @@ -316,7 +357,7 @@ Time execution." (get identity gc-start gc-end)) result)) -(define (profile repl form . opts) +(define-meta-command (profile repl form . opts) "profile FORM Profile execution." (apply vm-profile @@ -329,29 +370,28 @@ Profile execution." ;;; Debug commands ;;; -(define (backtrace repl) +(define-meta-command (backtrace repl) "backtrace Display backtrace." (vm-backtrace (repl-vm repl))) -(define (debugger repl) +(define-meta-command (debugger repl) "debugger Start debugger." (vm-debugger (repl-vm repl))) -(define (trace repl form . opts) +(define-meta-command (trace repl form . opts) "trace FORM Trace execution. -s Display stack -l Display local variables - -e Display external variables -b Bytecode level trace" (apply vm-trace (repl-vm repl) (repl-compile repl (repl-parse repl form)) opts)) -(define (step repl) +(define-meta-command (step repl) "step FORM Step execution." (display "Not implemented yet\n")) @@ -362,12 +402,12 @@ Step execution." ;;; (define guile:gc gc) -(define (gc repl) +(define-meta-command (gc repl) "gc Garbage collection." (guile:gc)) -(define (statistics repl) +(define-meta-command (statistics repl) "statistics Display statistics." (let ((this-tms (times)) diff --git a/module/system/repl/common.scm b/module/system/repl/common.scm index bc3242375..2db4518ad 100644 --- a/module/system/repl/common.scm +++ b/module/system/repl/common.scm @@ -2,25 +2,24 @@ ;; Copyright (C) 2001 Free Software Foundation, Inc. -;; 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 2, 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 COPYING. If not, write to -;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. +;;; This library is free software; you can redistribute it and/or +;;; modify it under the terms of the GNU Lesser General Public +;;; License as published by the Free Software Foundation; either +;;; version 3 of the License, or (at your option) any later version. +;;; +;;; This library is distributed in the hope that it will be useful, +;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;; Lesser General Public License for more details. +;;; +;;; You should have received a copy of the GNU Lesser General Public +;;; License along with this library; if not, write to the Free Software +;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Code: (define-module (system repl common) - #:use-syntax (system base syntax) + #:use-module (system base syntax) #:use-module (system base compile) #:use-module (system base language) #:use-module (system vm vm) diff --git a/module/system/repl/describe.scm b/module/system/repl/describe.scm index 0563def90..590d2235a 100644 --- a/module/system/repl/describe.scm +++ b/module/system/repl/describe.scm @@ -2,20 +2,19 @@ ;; Copyright (C) 2001 Free Software Foundation, Inc. -;; 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 2, 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 COPYING. If not, write to -;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. +;;; This library is free software; you can redistribute it and/or +;;; modify it under the terms of the GNU Lesser General Public +;;; License as published by the Free Software Foundation; either +;;; version 3 of the License, or (at your option) any later version. +;;; +;;; This library is distributed in the hope that it will be useful, +;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;; Lesser General Public License for more details. +;;; +;;; You should have received a copy of the GNU Lesser General Public +;;; License along with this library; if not, write to the Free Software +;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Code: diff --git a/module/system/repl/repl.scm b/module/system/repl/repl.scm index 76e7bfe3f..2f4a3783a 100644 --- a/module/system/repl/repl.scm +++ b/module/system/repl/repl.scm @@ -1,26 +1,26 @@ ;;; Read-Eval-Print Loop -;; Copyright (C) 2001 Free Software Foundation, Inc. +;; Copyright (C) 2001, 2009 Free Software Foundation, Inc. -;; 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 2, or (at your option) -;; any later version. +;; This library is free software; you can redistribute it and/or +;; modify it under the terms of the GNU Lesser General Public +;; License as published by the Free Software Foundation; either +;; version 3 of the License, or (at your option) any later version. ;; -;; This program is distributed in the hope that it will be useful, +;; This library is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; Lesser General Public License for more details. ;; -;; You should have received a copy of the GNU General Public License -;; along with this program; see the file COPYING. If not, write to -;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. +;; You should have received a copy of the GNU Lesser General Public +;; License along with this library; if not, write to the Free Software +;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +;; 02110-1301 USA ;;; Code: (define-module (system repl repl) - #:use-syntax (system base syntax) + #:use-module (system base syntax) #:use-module (system base pmatch) #:use-module (system base compile) #:use-module (system base language) @@ -28,7 +28,6 @@ #:use-module (system repl command) #:use-module (system vm vm) #:use-module (system vm debug) - #:use-module (ice-9 rdelim) #:export (start-repl call-with-backtrace)) (define meta-command-token (cons 'meta 'command)) @@ -89,7 +88,7 @@ (catch #t (lambda () (%start-stack #t thunk)) default-catch-handler - pre-unwind-handler-dispatch)) + default-pre-unwind-handler)) (define-macro (with-backtrace form) `(call-with-backtrace (lambda () ,form))) @@ -103,11 +102,14 @@ (cond ((eqv? exp (if #f #f))) ; read error, pass ((eq? exp meta-command-token) - (with-backtrace (meta-command repl (read-line)))) + (with-backtrace (meta-command repl))) ((eof-object? exp) (newline) (set! status '())) (else + ;; since the input port is line-buffered, consume up to the + ;; newline + (flush-to-newline) (with-backtrace (catch 'quit (lambda () @@ -135,3 +137,14 @@ ((char-whitespace? ch) (read-char) (next-char wait)) (else ch))) #f)) + +(define (flush-to-newline) + (if (char-ready?) + (let ((ch (peek-char))) + (if (and (not (eof-object? ch)) (char-whitespace? ch)) + (begin + (read-char) + (if (not (char=? ch #\newline)) + (flush-to-newline))))))) + + \ No newline at end of file diff --git a/module/system/vm/debug.scm b/module/system/vm/debug.scm index 3c5cfa201..740111257 100644 --- a/module/system/vm/debug.scm +++ b/module/system/vm/debug.scm @@ -20,7 +20,7 @@ ;;; Code: (define-module (system vm debug) - #:use-syntax (system base syntax) + #:use-module (system base syntax) #:use-module (system vm vm) #:use-module (system vm frame) #:use-module (ice-9 format) diff --git a/module/system/vm/frame.scm b/module/system/vm/frame.scm index a74d903da..332cd6172 100644 --- a/module/system/vm/frame.scm +++ b/module/system/vm/frame.scm @@ -1,6 +1,6 @@ ;;; Guile VM frame functions -;;; Copyright (C) 2001 Free Software Foundation, Inc. +;;; Copyright (C) 2001, 2009 Free Software Foundation, Inc. ;;; Copyright (C) 2005 Ludovic Courtès ;;; ;;; This program is free software; you can redistribute it and/or modify @@ -27,23 +27,22 @@ vm-frame-program vm-frame-local-ref vm-frame-local-set! vm-frame-return-address vm-frame-mv-return-address - vm-frame-dynamic-link vm-frame-external-link + vm-frame-dynamic-link vm-frame-stack vm-frame-number vm-frame-address - make-frame-chain - print-frame print-frame-chain-as-backtrace - frame-arguments frame-local-variables frame-external-variables - frame-environment - frame-variable-exists? frame-variable-ref frame-variable-set! - frame-object-name - frame-local-ref frame-external-link frame-local-set! - frame-return-address frame-program - frame-dynamic-link heap-frame?)) + make-frame-chain + print-frame print-frame-chain-as-backtrace + frame-arguments frame-local-variables + frame-environment + frame-variable-exists? frame-variable-ref frame-variable-set! + frame-object-name + frame-local-ref frame-local-set! + frame-return-address frame-program + frame-dynamic-link heap-frame?)) -;; fixme: avoid the dynamic-call? -(dynamic-call "scm_init_frames" (dynamic-link "libguile")) +(load-extension "libguile" "scm_init_frames") ;;; ;;; Frame chain @@ -159,24 +158,19 @@ (l '() (cons (frame-local-ref frame n) l))) ((< n 0) l)))) -(define (frame-external-variables frame) - (frame-external-link frame)) - -(define (frame-external-ref frame index) - (list-ref (frame-external-link frame) index)) - -(define (frame-external-set! frame index val) - (list-set! (frame-external-link frame) index val)) - (define (frame-binding-ref frame binding) - (if (binding:extp binding) - (frame-external-ref frame (binding:index binding)) - (frame-local-ref frame (binding:index binding)))) + (let ((x (frame-local-ref frame (binding:index binding)))) + (if (and (binding:boxed? binding) (variable? x)) + (variable-ref x) + x))) (define (frame-binding-set! frame binding val) - (if (binding:extp binding) - (frame-external-set! frame (binding:index binding) val) - (frame-local-set! frame (binding:index binding) val))) + (if (binding:boxed? binding) + (let ((v (frame-local-ref frame binding))) + (if (variable? v) + (variable-set! v val) + (frame-local-set! frame binding (make-variable val)))) + (frame-local-set! frame binding val))) ;; FIXME handle #f program-bindings return (define (frame-bindings frame addr) diff --git a/module/system/vm/instruction.scm b/module/system/vm/instruction.scm index c820e9952..403e9cdc7 100644 --- a/module/system/vm/instruction.scm +++ b/module/system/vm/instruction.scm @@ -2,20 +2,19 @@ ;; Copyright (C) 2001 Free Software Foundation, Inc. -;; 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 2, 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 COPYING. If not, write to -;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. +;;; This library is free software; you can redistribute it and/or +;;; modify it under the terms of the GNU Lesser General Public +;;; License as published by the Free Software Foundation; either +;;; version 3 of the License, or (at your option) any later version. +;;; +;;; This library is distributed in the hope that it will be useful, +;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;; Lesser General Public License for more details. +;;; +;;; You should have received a copy of the GNU Lesser General Public +;;; License along with this library; if not, write to the Free Software +;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Code: @@ -25,4 +24,4 @@ instruction-pops instruction-pushes instruction->opcode opcode->instruction)) -(dynamic-call "scm_init_instructions" (dynamic-link "libguile")) +(load-extension "libguile" "scm_init_instructions") diff --git a/module/system/vm/objcode.scm b/module/system/vm/objcode.scm index df1ff26e4..7c0490da6 100644 --- a/module/system/vm/objcode.scm +++ b/module/system/vm/objcode.scm @@ -2,20 +2,19 @@ ;; Copyright (C) 2001 Free Software Foundation, Inc. -;; 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 2, 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 COPYING. If not, write to -;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. +;;; This library is free software; you can redistribute it and/or +;;; modify it under the terms of the GNU Lesser General Public +;;; License as published by the Free Software Foundation; either +;;; version 3 of the License, or (at your option) any later version. +;;; +;;; This library is distributed in the hope that it will be useful, +;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;; Lesser General Public License for more details. +;;; +;;; You should have received a copy of the GNU Lesser General Public +;;; License along with this library; if not, write to the Free Software +;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Code: @@ -25,4 +24,4 @@ load-objcode write-objcode word-size byte-order)) -(dynamic-call "scm_init_objcodes" (dynamic-link "libguile")) +(load-extension "libguile" "scm_init_objcodes") diff --git a/module/system/vm/profile.scm b/module/system/vm/profile.scm index 2c17fc7a6..6ab418ac3 100644 --- a/module/system/vm/profile.scm +++ b/module/system/vm/profile.scm @@ -2,20 +2,19 @@ ;; Copyright (C) 2001 Free Software Foundation, Inc. -;; 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 2, 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 COPYING. If not, write to -;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. +;;; This library is free software; you can redistribute it and/or +;;; modify it under the terms of the GNU Lesser General Public +;;; License as published by the Free Software Foundation; either +;;; version 3 of the License, or (at your option) any later version. +;;; +;;; This library is distributed in the hope that it will be useful, +;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;; Lesser General Public License for more details. +;;; +;;; You should have received a copy of the GNU Lesser General Public +;;; License along with this library; if not, write to the Free Software +;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Code: diff --git a/module/system/vm/program.scm b/module/system/vm/program.scm index 7e4007b75..755c606e2 100644 --- a/module/system/vm/program.scm +++ b/module/system/vm/program.scm @@ -1,30 +1,29 @@ ;;; Guile VM program functions -;;; Copyright (C) 2001 Free Software Foundation, Inc. -;;; Copyright (C) 2005 Ludovic Courtès +;;; Copyright (C) 2001, 2009 Free Software Foundation, Inc. ;;; -;;; 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 2 of the License, or -;;; (at your option) any later version. +;;; This library is free software; you can redistribute it and/or +;;; modify it under the terms of the GNU Lesser General Public +;;; License as published by the Free Software Foundation; either +;;; version 3 of the License, or (at your option) any later version. ;;; -;;; This program is distributed in the hope that it will be useful, +;;; This library is distributed in the hope that it will be useful, ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;; GNU General Public License for more details. +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;; Lesser General Public License for more details. ;;; -;;; You should have received a copy of the GNU General Public License -;;; along with this program; if not, write to the Free Software -;;; Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +;;; You should have received a copy of the GNU Lesser General Public +;;; License along with this library; if not, write to the Free Software +;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Code: (define-module (system vm program) #:export (make-program - arity:nargs arity:nrest arity:nlocs arity:nexts + arity:nargs arity:nrest arity:nlocs - make-binding binding:name binding:extp binding:index + make-binding binding:name binding:boxed? binding:index binding:start binding:end source:addr source:line source:column source:file @@ -32,21 +31,20 @@ program-properties program-property program-documentation program-name program-arguments - program-arity program-external-set! program-meta + program-arity program-meta program-objcode program? program-objects - program-module program-base program-external)) + program-module program-base program-free-variables)) -(dynamic-call "scm_init_programs" (dynamic-link "libguile")) +(load-extension "libguile" "scm_init_programs") (define arity:nargs car) (define arity:nrest cadr) (define arity:nlocs caddr) -(define arity:nexts cadddr) -(define (make-binding name extp index start end) - (list name extp index start end)) +(define (make-binding name boxed? index start end) + (list name boxed? index start end)) (define (binding:name b) (list-ref b 0)) -(define (binding:extp b) (list-ref b 1)) +(define (binding:boxed? b) (list-ref b 1)) (define (binding:index b) (list-ref b 2)) (define (binding:start b) (list-ref b 3)) (define (binding:end b) (list-ref b 4)) diff --git a/module/system/vm/trace.scm b/module/system/vm/trace.scm index 00f013c9d..d8165f202 100644 --- a/module/system/vm/trace.scm +++ b/module/system/vm/trace.scm @@ -1,26 +1,25 @@ ;;; Guile VM tracer -;; Copyright (C) 2001 Free Software Foundation, Inc. +;; Copyright (C) 2001, 2009 Free Software Foundation, Inc. -;; 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 2, 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 COPYING. If not, write to -;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. +;;; This library is free software; you can redistribute it and/or +;;; modify it under the terms of the GNU Lesser General Public +;;; License as published by the Free Software Foundation; either +;;; version 3 of the License, or (at your option) any later version. +;;; +;;; This library is distributed in the hope that it will be useful, +;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;; Lesser General Public License for more details. +;;; +;;; You should have received a copy of the GNU Lesser General Public +;;; License along with this library; if not, write to the Free Software +;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Code: (define-module (system vm trace) - #:use-syntax (system base syntax) + #:use-module (system base syntax) #:use-module (system vm vm) #:use-module (system vm frame) #:use-module (ice-9 format) @@ -55,8 +54,7 @@ ((null? opts) (newline)) (case (car opts) ((:s) (puts (truncate! (vm-fetch-stack vm) 3))) - ((:l) (puts (vm-fetch-locals vm))) - ((:e) (puts (vm-fetch-externals vm)))))) + ((:l) (puts (vm-fetch-locals vm)))))) (define (trace-apply vm) (if (vm-option vm 'trace-first) diff --git a/module/system/vm/vm.scm b/module/system/vm/vm.scm index de5c3fa21..48dc4f2b8 100644 --- a/module/system/vm/vm.scm +++ b/module/system/vm/vm.scm @@ -32,7 +32,7 @@ vm-next-hook vm-apply-hook vm-boot-hook vm-return-hook vm-break-hook vm-exit-hook vm-halt-hook vm-enter-hook)) -(dynamic-call "scm_init_vm" (dynamic-link "libguile")) +(load-extension "libguile" "scm_init_vm") (define (vms:time stat) (vector-ref stat 0)) (define (vms:clock stat) (vector-ref stat 1)) diff --git a/module/system/xref.scm b/module/system/xref.scm index ea419079f..906ec8e4a 100644 --- a/module/system/xref.scm +++ b/module/system/xref.scm @@ -1,30 +1,33 @@ ;;;; Copyright (C) 2009 Free Software Foundation, Inc. -;;;; +;;;; ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either ;;;; version 2.1 of the License, or (at your option) any later version. -;;;; +;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;;;; Lesser General Public License for more details. -;;;; +;;;; ;;;; You should have received a copy of the GNU Lesser General Public ;;;; License along with this library; if not, write to the Free Software ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -;;;; +;;;; (define-module (system xref) #:use-module (system base pmatch) #:use-module (system base compile) #:use-module (system vm program) + #:use-module (srfi srfi-1) #:export (*xref-ignored-modules* procedure-callees procedure-callers)) (define (program-callee-rev-vars prog) + (define (cons-uniq x y) + (if (memq x y) y (cons x y))) (cond ((program-objects prog) => (lambda (objects) @@ -32,7 +35,7 @@ (progv (make-vector (vector-length objects) #f)) (asm (decompile (program-objcode prog) #:to 'assembly))) (pmatch asm - ((load-program ,nargs ,nrest ,nlocs ,next ,labels ,len . ,body) + ((load-program ,nargs ,nrest ,nlocs ,labels ,len . ,body) (for-each (lambda (x) (pmatch x @@ -44,19 +47,19 @@ ((= i n) out) ((program? (vector-ref objects i)) (lp (1+ i) - (append (program-callee-rev-vars (vector-ref objects i)) - out))) + (fold cons-uniq out + (program-callee-rev-vars (vector-ref objects i))))) ((vector-ref progv i) (let ((obj (vector-ref objects i))) (if (variable? obj) - (lp (1+ i) (cons obj out)) + (lp (1+ i) (cons-uniq obj out)) ;; otherwise it's an unmemoized binding (pmatch obj (,sym (guard (symbol? sym)) (let ((v (module-variable (or (program-module prog) the-root-module) sym))) - (lp (1+ i) (if v (cons v out) out)))) + (lp (1+ i) (if v (cons-uniq v out) out)))) ((,mod ,sym ,public?) ;; hm, hacky. (let* ((m (nested-ref the-root-module @@ -68,7 +71,7 @@ m) sym)))) (lp (1+ i) - (if v (cons v out) out)))))))) + (if v (cons-uniq v out) out)))))))) (else (lp (1+ i) out))))))) (else '()))) @@ -78,51 +81,95 @@ (else '()))) (define (procedure-callees prog) + "Evaluates to a list of the given program callees." (let lp ((in (procedure-callee-rev-vars prog)) (out '())) (cond ((null? in) out) ((variable-bound? (car in)) (lp (cdr in) (cons (variable-ref (car in)) out))) (else (lp (cdr in) out))))) +;; var -> ((module-name caller ...) ...) (define *callers-db* #f) +;; module-name -> (callee ...) +(define *module-callees-db* (make-hash-table)) +;; (module-name ...) +(define *tainted-modules* '()) (define *xref-ignored-modules* '((value-history))) (define (on-module-modified m) - (if (not (member (module-name m) *xref-ignored-modules*)) - (set! *callers-db* #f))) + (let ((name (module-name m))) + (if (and (not (member name *xref-ignored-modules*)) + (not (member name *tainted-modules*)) + (pair? name)) + (set! *tainted-modules* (cons name *tainted-modules*))))) -(define (ensure-callers-db) - (let ((visited '()) - (db #f)) - (define (visit-variable var) +(define (add-caller callee caller mod-name) + (let ((all-callers (hashq-ref *callers-db* callee))) + (if (not all-callers) + (hashq-set! *callers-db* callee `((,mod-name ,caller))) + (let ((callers (assoc mod-name all-callers))) + (if callers + (if (not (member caller callers)) + (set-cdr! callers (cons caller (cdr callers)))) + (hashq-set! *callers-db* callee + (cons `(,mod-name ,caller) all-callers))))))) + +(define (forget-callers callee mod-name) + (hashq-set! *callers-db* callee + (assoc-remove! (hashq-ref *callers-db* callee '()) mod-name))) + +(define (add-callees callees mod-name) + (hash-set! *module-callees-db* mod-name + (append callees (hash-ref *module-callees-db* mod-name '())))) + +(define (untaint-modules) + (define (untaint m) + (for-each (lambda (callee) (forget-callers callee m)) + (hash-ref *module-callees-db* m '())) + (ensure-callers-db m)) + (ensure-callers-db #f) + (for-each untaint *tainted-modules*) + (set! *tainted-modules* '())) + +(define (ensure-callers-db mod-name) + (let ((mod (and mod-name (resolve-module mod-name))) + (visited #f)) + (define (visit-variable var recurse mod-name) (if (variable-bound? var) (let ((x (variable-ref var))) (cond + ((and visited (hashq-ref visited x))) ((procedure? x) - (for-each - (lambda (callee) - (if (variable-bound? callee) - (let ((y (variable-ref callee))) - (hashq-set! db callee (cons x (hashq-ref db callee '())))))) - (procedure-callee-rev-vars x))) - ((and (module? x) (not (memq x visited))) - (visit-module x)))))) + (if visited (hashq-set! visited x #t)) + (let ((callees (filter variable-bound? + (procedure-callee-rev-vars x)))) + (for-each (lambda (callee) + (add-caller callee x mod-name)) + callees) + (add-callees callees mod-name))) + ((and recurse (module? x)) + (visit-module x #t)))))) - (define (visit-module mod) - (set! visited (cons mod visited)) + (define (visit-module mod recurse) + (if visited (hashq-set! visited mod #t)) (if (not (memq on-module-modified (module-observers mod))) (module-observe mod on-module-modified)) - (module-for-each (lambda (sym var) - (visit-variable var)) - mod)) + (let ((name (module-name mod))) + (module-for-each (lambda (sym var) + (visit-variable var recurse name)) + mod))) - (if (not *callers-db*) - (begin - (set! db (make-hash-table)) - (visit-module the-root-module) - (set! *callers-db* db))))) + (cond ((and (not mod-name) (not *callers-db*)) + (set! *callers-db* (make-hash-table 1000)) + (set! visited (make-hash-table 1000)) + (visit-module the-root-module #t)) + (mod-name (visit-module mod #f))))) (define (procedure-callers var) + "Returns an association list, keyed by module name, of known callers +of the given procedure. The latter can specified directly as a +variable, a symbol (which gets resolved in the current module) or a +pair of the form (module-name . variable-name), " (let ((v (cond ((variable? var) var) ((symbol? var) (module-variable (current-module) var)) (else @@ -130,6 +177,6 @@ ((,modname . ,sym) (module-variable (resolve-module modname) sym)) (else - (error "expected a variable, symbol, or (modname sym)" var))))))) - (ensure-callers-db) + (error "expected a variable, symbol, or (modname . sym)" var))))))) + (untaint-modules) (hashq-ref *callers-db* v '()))) diff --git a/qt/Makefile.am b/qt/Makefile.am index fc9951d30..8a15fb6ff 100644 --- a/qt/Makefile.am +++ b/qt/Makefile.am @@ -4,20 +4,20 @@ ## ## This file is part of GUILE. ## -## GUILE 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, or +## GUILE is free software; you can redistribute it and/or modify it +## under the terms of the GNU Lesser General Public License as +## published by the Free Software Foundation; either version 3, or ## (at your option) any later version. -## +## ## GUILE 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 GUILE; see the file COPYING. If not, write -## to the Free Software Foundation, Inc., 51 Franklin Street, Fifth -## Floor, Boston, MA 02110-1301 USA +## GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with GUILE; see the file COPYING.LESSER. If not, +## write to the Free Software Foundation, Inc., 51 Franklin Street, +## Fifth Floor, Boston, MA 02110-1301 USA AUTOMAKE_OPTIONS = gnu diff --git a/qt/md/Makefile.am b/qt/md/Makefile.am index 7500dc66c..e5b29e96e 100644 --- a/qt/md/Makefile.am +++ b/qt/md/Makefile.am @@ -4,20 +4,20 @@ ## ## This file is part of GUILE. ## -## GUILE 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, or +## GUILE is free software; you can redistribute it and/or modify it +## under the terms of the GNU Lesser General Public License as +## published by the Free Software Foundation; either version 3, or ## (at your option) any later version. -## +## ## GUILE 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 GUILE; see the file COPYING. If not, write -## to the Free Software Foundation, Inc., 51 Franklin Street, Fifth -## Floor, Boston, MA 02110-1301 USA +## GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with GUILE; see the file COPYING.LESSER. If not, +## write to the Free Software Foundation, Inc., 51 Franklin Street, +## Fifth Floor, Boston, MA 02110-1301 USA AUTOMAKE_OPTIONS = gnu diff --git a/qt/time/Makefile.am b/qt/time/Makefile.am index 735620330..bdce61f38 100644 --- a/qt/time/Makefile.am +++ b/qt/time/Makefile.am @@ -4,20 +4,20 @@ ## ## This file is part of GUILE. ## -## GUILE 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, or +## GUILE is free software; you can redistribute it and/or modify it +## under the terms of the GNU Lesser General Public License as +## published by the Free Software Foundation; either version 3, or ## (at your option) any later version. -## +## ## GUILE 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 GUILE; see the file COPYING. If not, write -## to the Free Software Foundation, Inc., 51 Franklin Street, Fifth -## Floor, Boston, MA 02110-1301 USA +## GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with GUILE; see the file COPYING.LESSER. If not, +## write to the Free Software Foundation, Inc., 51 Franklin Street, +## Fifth Floor, Boston, MA 02110-1301 USA AUTOMAKE_OPTIONS = gnu diff --git a/scripts/Makefile.am b/scripts/Makefile.am deleted file mode 100644 index ca96da78d..000000000 --- a/scripts/Makefile.am +++ /dev/null @@ -1,70 +0,0 @@ -## Process this file with automake to produce Makefile.in. -## -## Copyright (C) 2002, 2006, 2008 Free Software Foundation, Inc. -## -## This file is part of GUILE. -## -## GUILE 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, or -## (at your option) any later version. -## -## GUILE 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 GUILE; see the file COPYING. If not, write -## to the Free Software Foundation, Inc., 51 Franklin Street, Fifth -## Floor, Boston, MA 02110-1301 USA - -AUTOMAKE_OPTIONS = gnu - -# These should be installed and distributed. -scripts_sources = \ - PROGRAM \ - autofrisk \ - compile \ - disassemble \ - display-commentary \ - doc-snarf \ - frisk \ - generate-autoload \ - lint \ - punify \ - read-scheme-source \ - read-text-outline \ - use2dot \ - snarf-check-and-output-texi \ - summarize-guile-TODO \ - scan-api \ - api-diff \ - read-rfc822 \ - snarf-guile-m4-docs - -subpkgdatadir = $(pkgdatadir)/$(GUILE_EFFECTIVE_VERSION)/scripts -subpkgdata_SCRIPTS = $(scripts_sources) - -EXTRA_DIST = $(scripts_sources) ChangeLog-2008 - -list: - @echo $(scripts_sources) - -include $(top_srcdir)/am/pre-inst-guile - -overview: $(scripts_sources) - @echo '----------------------------' - @echo Overview - @echo I. Commentaries - @echo II. Module Interfaces - @echo '----------------------------' - @echo I. Commentaries - @echo '----------------------------' - $(preinstguiletool)/display-commentary $^ - @echo '----------------------------' - @echo II. Module Interfaces - @echo '----------------------------' - $(preinstguiletool)/frisk $^ - -# Makefile.am ends here diff --git a/scripts/compile b/scripts/compile deleted file mode 100755 index 6651722f0..000000000 --- a/scripts/compile +++ /dev/null @@ -1,143 +0,0 @@ -#!/bin/sh -# -*- scheme -*- -exec ${GUILE-guile} -e '(@ (scripts compile) compile)' -s $0 "$@" -!# -;;; Compile --- Command-line Guile Scheme compiler - -;; Copyright 2005,2008,2009 Free Software Foundation, Inc. -;; -;; 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 2, 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 software; see the file COPYING. If not, write to -;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;; Boston, MA 02110-1301 USA - -;;; Author: Ludovic Courtès -;;; Author: Andy Wingo - -;;; Commentary: - -;; Usage: compile [ARGS] -;; -;; PROGRAM does something. -;; -;; TODO: Write it! - -;;; Code: - -(define-module (scripts compile) - #:use-module ((system base compile) #:select (compile-file)) - #:use-module (srfi srfi-1) - #:use-module (srfi srfi-13) - #:use-module (srfi srfi-37) - #:export (compile)) - - -(define (fail . messages) - (format (current-error-port) - (string-concatenate `("error: " ,@messages "~%"))) - (exit 1)) - -(define %options - ;; Specifications of the command-line options. - (list (option '(#\h "help") #f #f - (lambda (opt name arg result) - (alist-cons 'help? #t result))) - - (option '(#\L "load-path") #t #f - (lambda (opt name arg result) - (let ((load-path (assoc-ref result 'load-path))) - (alist-cons 'load-path (cons arg load-path) - result)))) - (option '(#\o "output") #t #f - (lambda (opt name arg result) - (if (assoc-ref result 'output-file) - (fail "`-o' option cannot be specified more than once") - (alist-cons 'output-file arg result)))) - - (option '(#\O "optimize") #f #f - (lambda (opt name arg result) - (alist-cons 'optimize? #t result))) - (option '(#\e "expand-only") #f #f - (lambda (opt name arg result) - (alist-cons 'expand-only? #t result))) - (option '(#\t "translate-only") #f #f - (lambda (opt name arg result) - (alist-cons 'translate-only? #t result))) - (option '(#\c "compile-only") #f #f - (lambda (opt name arg result) - (alist-cons 'compile-only? #t result))))) - -(define (parse-args args) - "Parse argument list @var{args} and return an alist with all the relevant -options." - (args-fold args %options - (lambda (opt name arg result) - (format (current-error-port) "~A: unrecognized option" opt) - (exit 1)) - (lambda (file result) - (let ((input-files (assoc-ref result 'input-files))) - (alist-cons 'input-files (cons file input-files) - result))) - - ;; default option values - '((input-files) - (load-path)))) - - -(define (compile args) - (let* ((options (parse-args (cdr args))) - (help? (assoc-ref options 'help?)) - (optimize? (assoc-ref options 'optimize?)) - (expand-only? (assoc-ref options 'expand-only?)) - (translate-only? (assoc-ref options 'translate-only?)) - (compile-only? (assoc-ref options 'compile-only?)) - (input-files (assoc-ref options 'input-files)) - (output-file (assoc-ref options 'output-file)) - (load-path (assoc-ref options 'load-path))) - (if (or help? (null? input-files)) - (begin - (format #t "Usage: compile [OPTION] FILE... -Compile each Guile Scheme source file FILE into a Guile object. - - -h, --help print this help message - - -L, --load-path=DIR add DIR to the front of the module load path - -o, --output=OFILE write output to OFILE - - -O, --optimize turn on optimizations - -e, --expand-only only go through the code expansion stage - -t, --translate-only stop after the translation to GHIL - -c, --compile-only stop after the compilation to GLIL - -Report bugs to .~%") - (exit 0))) - - (set! %load-path (append load-path %load-path)) - - (let ((compile-opts (append (if optimize? '(#:O) '()) - (if expand-only? '(#:e) '()) - (if translate-only? '(#:t) '()) - (if compile-only? '(#:c) '())))) - (if output-file - (if (and (not (null? input-files)) - (null? (cdr input-files))) - (compile-file (car input-files) output-file) - (fail "`-o' option can only be specified " - "when compiling a single file")) - (for-each (lambda (file) - (apply compile-file file compile-opts)) - input-files))))) - -;;; Local Variables: -;;; coding: latin-1 -;;; End: diff --git a/scripts/disassemble b/scripts/disassemble deleted file mode 100755 index 71ec05705..000000000 --- a/scripts/disassemble +++ /dev/null @@ -1,41 +0,0 @@ -#!/bin/sh -# -*- scheme -*- -exec ${GUILE-guile} -e '(@ (scripts disassemble) disassemble)' -s $0 "$@" -!# -;;; Disassemble --- Disassemble .go files into something human-readable - -;; Copyright 2005,2008 Free Software Foundation, Inc. -;; -;; 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 2, 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 software; see the file COPYING. If not, write to -;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;; Boston, MA 02110-1301 USA - -;;; Author: Ludovic Courtès -;;; Author: Andy Wingo - -;;; Commentary: - -;; Usage: disassemble [ARGS] - -;;; Code: - -(define-module (scripts disassemble) - #:use-module (system vm objcode) - #:use-module (language assembly disassemble) - #:export (disassemble)) - -(define (disassemble args) - (for-each (lambda (file) - (disassemble (load-objcode file))) - (cdr args))) diff --git a/srfi/Makefile.am b/srfi/Makefile.am index 02fa12b04..648603007 100644 --- a/srfi/Makefile.am +++ b/srfi/Makefile.am @@ -4,20 +4,20 @@ ## ## This file is part of GUILE. ## -## GUILE 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, or +## GUILE is free software; you can redistribute it and/or modify it +## under the terms of the GNU Lesser General Public License as +## published by the Free Software Foundation; either version 3, or ## (at your option) any later version. ## ## GUILE 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. +## GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU General Public -## License along with GUILE; see the file COPYING. If not, write -## to the Free Software Foundation, Inc., 51 Franklin Street, Fifth -## Floor, Boston, MA 02110-1301 USA +## You should have received a copy of the GNU Lesser General Public +## License along with GUILE; see the file COPYING.LESSER. If not, +## write to the Free Software Foundation, Inc., 51 Franklin Street, +## Fifth Floor, Boston, MA 02110-1301 USA AUTOMAKE_OPTIONS = gnu diff --git a/srfi/srfi-1.c b/srfi/srfi-1.c index dc218ab04..02f46fca0 100644 --- a/srfi/srfi-1.c +++ b/srfi/srfi-1.c @@ -4,18 +4,19 @@ * Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ #ifdef HAVE_CONFIG_H diff --git a/srfi/srfi-1.h b/srfi/srfi-1.h index 936586697..5797579cc 100644 --- a/srfi/srfi-1.h +++ b/srfi/srfi-1.h @@ -5,18 +5,19 @@ * Copyright (C) 2002, 2003, 2005, 2006 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/srfi/srfi-13.c b/srfi/srfi-13.c index dd5ce9b15..61a960e5d 100644 --- a/srfi/srfi-13.c +++ b/srfi/srfi-13.c @@ -3,18 +3,19 @@ * Copyright (C) 2001, 2004, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/srfi/srfi-13.h b/srfi/srfi-13.h index 8007d565b..a110ffd6d 100644 --- a/srfi/srfi-13.h +++ b/srfi/srfi-13.h @@ -6,18 +6,19 @@ * Copyright (C) 2001, 2004, 2006 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/srfi/srfi-14.c b/srfi/srfi-14.c index 1a7297b82..9f6ad8bc0 100644 --- a/srfi/srfi-14.c +++ b/srfi/srfi-14.c @@ -3,18 +3,19 @@ * Copyright (C) 2001, 2004, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ #ifdef HAVE_CONFIG_H diff --git a/srfi/srfi-14.h b/srfi/srfi-14.h index b1f4ae726..a793159c5 100644 --- a/srfi/srfi-14.h +++ b/srfi/srfi-14.h @@ -5,18 +5,19 @@ * Copyright (C) 2001, 2004, 2006 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/srfi/srfi-4.c b/srfi/srfi-4.c index f40c6b319..9b32b61a9 100644 --- a/srfi/srfi-4.c +++ b/srfi/srfi-4.c @@ -3,18 +3,19 @@ * Copyright (C) 2001, 2004, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ /* This file is now empty since all its procedures are now in the diff --git a/srfi/srfi-4.h b/srfi/srfi-4.h index 079219ace..0439675da 100644 --- a/srfi/srfi-4.h +++ b/srfi/srfi-4.h @@ -5,18 +5,19 @@ * Copyright (C) 2001, 2006 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/srfi/srfi-60.c b/srfi/srfi-60.c index 7d89ca039..989898f9c 100644 --- a/srfi/srfi-60.c +++ b/srfi/srfi-60.c @@ -3,18 +3,19 @@ * Copyright (C) 2005, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ #ifdef HAVE_CONFIG_H diff --git a/srfi/srfi-60.h b/srfi/srfi-60.h index 030b32525..47a8cf766 100644 --- a/srfi/srfi-60.h +++ b/srfi/srfi-60.h @@ -3,18 +3,19 @@ * Copyright (C) 2005, 2006 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/test-suite/Makefile.am b/test-suite/Makefile.am index 05a7fe4d9..476d6e688 100644 --- a/test-suite/Makefile.am +++ b/test-suite/Makefile.am @@ -4,20 +4,20 @@ ## ## This file is part of GUILE. ## -## GUILE 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, or -## (at your option) any later version. +## GUILE is free software; you can redistribute it and/or modify it +## under the terms of the GNU Lesser General Public License as +## published by the Free Software Foundation; either version 3, or +## (at your option) any later version. ## -## GUILE 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. +## GUILE is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU General Public -## License along with GUILE; see the file COPYING. If not, write -## to the Free Software Foundation, Inc., 51 Franklin Street, Fifth -## Floor, Boston, MA 02110-1301 USA +## You should have received a copy of the GNU Lesser General Public +## License along with GUILE; see the file COPYING.LESSER. If not, +## write to the Free Software Foundation, Inc., 51 Franklin Street, +## Fifth Floor, Boston, MA 02110-1301 USA SUBDIRS = standalone @@ -26,6 +26,7 @@ SCM_TESTS = tests/alist.test \ tests/arbiters.test \ tests/asm-to-bytecode.test \ tests/bit-operations.test \ + tests/bytevectors.test \ tests/c-api.test \ tests/chars.test \ tests/common-list.test \ @@ -61,6 +62,7 @@ SCM_TESTS = tests/alist.test \ tests/q.test \ tests/r4rs.test \ tests/r5rs_pitfall.test \ + tests/r6rs-ports.test \ tests/ramap.test \ tests/reader.test \ tests/receive.test \ @@ -92,6 +94,7 @@ SCM_TESTS = tests/alist.test \ tests/syntax.test \ tests/threads.test \ tests/time.test \ + tests/tree-il.test \ tests/unif.test \ tests/version.test \ tests/weaks.test diff --git a/test-suite/guile-test b/test-suite/guile-test index 1e1c70a77..65b0533c8 100755 --- a/test-suite/guile-test +++ b/test-suite/guile-test @@ -7,20 +7,20 @@ ;;;; ;;;; Copyright (C) 1999, 2001, 2006 Free Software Foundation, Inc. ;;;; -;;;; 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 2, or (at your option) -;;;; any later version. +;;;; This program is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3, 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. +;;;; GNU Lesser General Public License for more details. ;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this software; see the file COPYING. If not, write to -;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;;; Boston, MA 02110-1301 USA +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this software; see the file COPYING.LESSER. +;;;; If not, write to the Free Software Foundation, Inc., 51 Franklin +;;;; Street, Fifth Floor, Boston, MA 02110-1301 USA ;;;; Usage: [guile -e main -s] guile-test [OPTIONS] [TEST ...] diff --git a/test-suite/lib.scm b/test-suite/lib.scm index c4ddf9e7c..8190d1fd0 100644 --- a/test-suite/lib.scm +++ b/test-suite/lib.scm @@ -1,20 +1,20 @@ ;;;; test-suite/lib.scm --- generic support for testing -;;;; Copyright (C) 1999, 2000, 2001, 2004, 2006, 2007 Free Software Foundation, Inc. +;;;; Copyright (C) 1999, 2000, 2001, 2004, 2006, 2007, 2009 Free Software Foundation, Inc. ;;;; -;;;; 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 2, or (at your option) -;;;; any later version. +;;;; This program is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3, 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. +;;;; GNU Lesser General Public License for more details. ;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this software; see the file COPYING. If not, write to -;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;;; Boston, MA 02110-1301 USA +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this software; see the file COPYING.LESSER. +;;;; If not, write to the Free Software Foundation, Inc., 51 Franklin +;;;; Street, Fifth Floor, Boston, MA 02110-1301 USA (define-module (test-suite lib) :use-module (ice-9 stack-catch) @@ -32,6 +32,7 @@ exception:system-error exception:miscellaneous-error exception:string-contains-nul + exception:read-error ;; Reporting passes and failures. run-test @@ -265,6 +266,8 @@ (cons 'system-error ".*")) (define exception:miscellaneous-error (cons 'misc-error "^.*")) +(define exception:read-error + (cons 'read-error "^.*$")) ;; as per throw in scm_to_locale_stringn() (define exception:string-contains-nul @@ -317,20 +320,24 @@ (set! run-test local-run-test)) ;;; A short form for tests that are expected to pass, taken from Greg. -(defmacro pass-if (name . rest) - (if (and (null? rest) (pair? name)) - ;; presume this is a simple test, i.e. (pass-if (even? 2)) - ;; where the body should also be the name. - `(run-test ',name #t (lambda () ,name)) - `(run-test ,name #t (lambda () ,@rest)))) +(define-syntax pass-if + (syntax-rules () + ((_ name) + ;; presume this is a simple test, i.e. (pass-if (even? 2)) + ;; where the body should also be the name. + (run-test 'name #t (lambda () name))) + ((_ name rest ...) + (run-test name #t (lambda () rest ...))))) ;;; A short form for tests that are expected to fail, taken from Greg. -(defmacro expect-fail (name . rest) - (if (and (null? rest) (pair? name)) - ;; presume this is a simple test, i.e. (expect-fail (even? 2)) - ;; where the body should also be the name. - `(run-test ',name #f (lambda () ,name)) - `(run-test ,name #f (lambda () ,@rest)))) +(define-syntax expect-fail + (syntax-rules () + ((_ name) + ;; presume this is a simple test, i.e. (expect-fail (even? 2)) + ;; where the body should also be the name. + (run-test 'name #f (lambda () name))) + ((_ name rest ...) + (run-test name #f (lambda () rest ...))))) ;;; A helper function to implement the macros that test for exceptions. (define (run-test-exception name exception expect-pass thunk) @@ -362,12 +369,16 @@ (apply throw key proc message rest)))))))) ;;; A short form for tests that expect a certain exception to be thrown. -(defmacro pass-if-exception (name exception body . rest) - `(,run-test-exception ,name ,exception #t (lambda () ,body ,@rest))) +(define-syntax pass-if-exception + (syntax-rules () + ((_ name exception body rest ...) + (run-test-exception name exception #t (lambda () body rest ...))))) ;;; A short form for tests expected to fail to throw a certain exception. -(defmacro expect-fail-exception (name exception body . rest) - `(,run-test-exception ,name ,exception #f (lambda () ,body ,@rest))) +(define-syntax expect-fail-exception + (syntax-rules () + ((_ name exception body rest ...) + (run-test-exception name exception #f (lambda () body rest ...))))) ;;;; TEST NAMES diff --git a/test-suite/standalone/Makefile.am b/test-suite/standalone/Makefile.am index 854a4a028..a9905324e 100644 --- a/test-suite/standalone/Makefile.am +++ b/test-suite/standalone/Makefile.am @@ -4,20 +4,20 @@ ## ## This file is part of GUILE. ## -## GUILE 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, or -## (at your option) any later version. +## GUILE is free software; you can redistribute it and/or modify it +## under the terms of the GNU Lesser General Public License as +## published by the Free Software Foundation; either version 3, or +## (at your option) any later version. ## -## GUILE 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. +## GUILE is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU General Public -## License along with GUILE; see the file COPYING. If not, write -## to the Free Software Foundation, Inc., 51 Franklin Street, Fifth -## Floor, Boston, MA 02110-1301 USA +## You should have received a copy of the GNU Lesser General Public +## License along with GUILE; see the file COPYING.LESSER. If not, +## write to the Free Software Foundation, Inc., 51 Franklin Street, +## Fifth Floor, Boston, MA 02110-1301 USA # initializations so we can use += below. @@ -28,7 +28,8 @@ check_SCRIPTS = BUILT_SOURCES = EXTRA_DIST = -TESTS_ENVIRONMENT = "${top_builddir}/pre-inst-guile-env" +TESTS_ENVIRONMENT = \ + GUILE_AUTO_COMPILE=0 "${top_builddir}/meta/uninstalled-env" test_cflags = \ -I$(top_srcdir)/test-suite/standalone \ @@ -125,6 +126,15 @@ test_scm_take_locale_symbol_LDADD = ${top_builddir}/libguile/libguile.la check_PROGRAMS += test-scm-take-locale-symbol TESTS += test-scm-take-locale-symbol +# test-extensions +noinst_LTLIBRARIES += libtest-extensions.la +libtest_extensions_la_SOURCES = test-extensions-lib.c +libtest_extensions_la_CFLAGS = ${test_cflags} +libtest_extensions_la_LDFLAGS = -no-undefined -rpath `pwd` # so libtool will really build an .so +libtest_extensions_la_LIBADD = ${top_builddir}/libguile/libguile.la +check_SCRIPTS += test-extensions +TESTS += test-extensions + if BUILD_PTHREAD_SUPPORT diff --git a/test-suite/standalone/README b/test-suite/standalone/README index 4e0bd652e..164c6ab46 100644 --- a/test-suite/standalone/README +++ b/test-suite/standalone/README @@ -12,7 +12,7 @@ If you want to use a scheme script, prefix it as follows: !# Makefile.am will arrange for all tests (scripts or executables) to be -run under pre-inst-guile-env so that the PATH, LD_LIBRARY_PATH, and +run under uninstalled-env so that the PATH, LD_LIBRARY_PATH, and GUILE_LOAD_PATH will be augmented appropriately. The Makefile.am has an example of creating a shared library to be used diff --git a/test-suite/standalone/test-asmobs-lib.c b/test-suite/standalone/test-asmobs-lib.c index b85f923cd..c88556ab2 100644 --- a/test-suite/standalone/test-asmobs-lib.c +++ b/test-suite/standalone/test-asmobs-lib.c @@ -1,18 +1,19 @@ /* Copyright (C) 1999,2000,2001,2003, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ #ifndef HAVE_CONFIG_H diff --git a/test-suite/standalone/test-conversion.c b/test-suite/standalone/test-conversion.c index 92835f244..0dfa80a23 100644 --- a/test-suite/standalone/test-conversion.c +++ b/test-suite/standalone/test-conversion.c @@ -1,18 +1,19 @@ -/* Copyright (C) 1999,2000,2001,2003,2004, 2006, 2007, 2008 Free Software Foundation, Inc. +/* Copyright (C) 1999,2000,2001,2003,2004, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ #if HAVE_CONFIG_H @@ -680,31 +681,31 @@ test_8u (const char *str, scm_t_uintmax (*func) (SCM), const char *func_name, #define DEFSTST(f) static scm_t_intmax tst_##f (SCM x) { return f(x); } #define DEFUTST(f) static scm_t_uintmax tst_##f (SCM x) { return f(x); } -DEFSTST (scm_to_schar); -DEFUTST (scm_to_uchar); -DEFSTST (scm_to_char); -DEFSTST (scm_to_short); -DEFUTST (scm_to_ushort); -DEFSTST (scm_to_int); -DEFUTST (scm_to_uint); -DEFSTST (scm_to_long); -DEFUTST (scm_to_ulong); +DEFSTST (scm_to_schar) +DEFUTST (scm_to_uchar) +DEFSTST (scm_to_char) +DEFSTST (scm_to_short) +DEFUTST (scm_to_ushort) +DEFSTST (scm_to_int) +DEFUTST (scm_to_uint) +DEFSTST (scm_to_long) +DEFUTST (scm_to_ulong) #if SCM_SIZEOF_LONG_LONG != 0 -DEFSTST (scm_to_long_long); -DEFUTST (scm_to_ulong_long); +DEFSTST (scm_to_long_long) +DEFUTST (scm_to_ulong_long) #endif -DEFSTST (scm_to_ssize_t); -DEFUTST (scm_to_size_t); +DEFSTST (scm_to_ssize_t) +DEFUTST (scm_to_size_t) -DEFSTST (scm_to_int8); -DEFUTST (scm_to_uint8); -DEFSTST (scm_to_int16); -DEFUTST (scm_to_uint16); -DEFSTST (scm_to_int32); -DEFUTST (scm_to_uint32); +DEFSTST (scm_to_int8) +DEFUTST (scm_to_uint8) +DEFSTST (scm_to_int16) +DEFUTST (scm_to_uint16) +DEFSTST (scm_to_int32) +DEFUTST (scm_to_uint32) #ifdef SCM_HAVE_T_INT64 -DEFSTST (scm_to_int64); -DEFUTST (scm_to_uint64); +DEFSTST (scm_to_int64) +DEFUTST (scm_to_uint64) #endif #define TEST_8S(v,f,r,re,te) test_8s (v, tst_##f, #f, r, re, te) @@ -818,15 +819,60 @@ test_9 (double val, const char *result) } } +/* The `infinity' and `not-a-number' values. */ +static double guile_Inf, guile_NaN; + +/* Initialize GUILE_INF and GUILE_NAN. Taken from `guile_ieee_init ()' in + `libguile/numbers.c'. */ +static void +ieee_init (void) +{ +#ifdef INFINITY + /* C99 INFINITY, when available. + FIXME: The standard allows for INFINITY to be something that overflows + at compile time. We ought to have a configure test to check for that + before trying to use it. (But in practice we believe this is not a + problem on any system guile is likely to target.) */ + guile_Inf = INFINITY; +#elif HAVE_DINFINITY + /* OSF */ + extern unsigned int DINFINITY[2]; + guile_Inf = (*((double *) (DINFINITY))); +#else + double tmp = 1e+10; + guile_Inf = tmp; + for (;;) + { + guile_Inf *= 1e+10; + if (guile_Inf == tmp) + break; + tmp = guile_Inf; + } +#endif + +#ifdef NAN + /* C99 NAN, when available */ + guile_NaN = NAN; +#elif HAVE_DQNAN + { + /* OSF */ + extern unsigned int DQNAN[2]; + guile_NaN = (*((double *)(DQNAN))); + } +#else + guile_NaN = guile_Inf / guile_Inf; +#endif +} + static void test_from_double () { test_9 (12, "12.0"); test_9 (0.25, "0.25"); test_9 (0.1, "0.1"); - test_9 (1.0/0.0, "+inf.0"); - test_9 (-1.0/0.0, "-inf.0"); - test_9 (0.0/0.0, "+nan.0"); + test_9 (guile_Inf, "+inf.0"); + test_9 (-guile_Inf, "-inf.0"); + test_9 (guile_NaN, "+nan.0"); } typedef struct { @@ -880,8 +926,8 @@ test_to_double () test_10 ("12", 12.0, 0); test_10 ("0.25", 0.25, 0); test_10 ("1/4", 0.25, 0); - test_10 ("+inf.0", 1.0/0.0, 0); - test_10 ("-inf.0", -1.0/0.0, 0); + test_10 ("+inf.0", guile_Inf, 0); + test_10 ("-inf.0",-guile_Inf, 0); test_10 ("+1i", 0.0, 1); } @@ -1056,6 +1102,7 @@ tests (void *data, int argc, char **argv) int main (int argc, char *argv[]) { + ieee_init (); scm_boot_guile (argc, argv, tests, NULL); return 0; } diff --git a/test-suite/standalone/test-extensions b/test-suite/standalone/test-extensions new file mode 100755 index 000000000..bea432de2 --- /dev/null +++ b/test-suite/standalone/test-extensions @@ -0,0 +1,14 @@ +#!/bin/sh +exec guile -q -s "$0" "$@" +!# + +(load-extension "libtest-extensions" "libtest_extensions_init") +(load-extension "libtest-extensions" "libtest_extensions_init2") + +(or (= init2-count 1) + (error "init2 called more or less than one time")) + + +;; Local Variables: +;; mode: scheme +;; End: \ No newline at end of file diff --git a/test-suite/standalone/test-extensions-lib.c b/test-suite/standalone/test-extensions-lib.c new file mode 100644 index 000000000..7c8678895 --- /dev/null +++ b/test-suite/standalone/test-extensions-lib.c @@ -0,0 +1,44 @@ +/* Copyright (C) 1999,2000,2001,2003, 2006, 2008 Free Software Foundation, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#ifndef HAVE_CONFIG_H +# include +#endif + +#include + +SCM init2_count; + +void libtest_extensions_init2 (void); +void libtest_extensions_init (void); + +void +libtest_extensions_init2 (void) +{ + scm_variable_set_x (init2_count, + scm_from_int (scm_to_int (scm_variable_ref (init2_count)) + 1)); +} + +void +libtest_extensions_init (void) +{ + scm_c_define ("init2-count", scm_from_int (0)); + init2_count = scm_permanent_object (scm_c_lookup ("init2-count")); + scm_c_register_extension ("libtest-extensions", "libtest_extensions_init2", + (scm_t_extension_init_func)libtest_extensions_init2, NULL); +} diff --git a/test-suite/standalone/test-fast-slot-ref.in b/test-suite/standalone/test-fast-slot-ref.in index 5bd063876..e0708ab9d 100644 --- a/test-suite/standalone/test-fast-slot-ref.in +++ b/test-suite/standalone/test-fast-slot-ref.in @@ -2,19 +2,20 @@ # Copyright (C) 2006 Free Software Foundation, Inc. # -# This library is free software; you can redistribute it and/or modify it -# under the terms of the GNU Lesser General Public License as published by -# the Free Software Foundation; either version 2.1 of the License, or (at -# your option) any later version. +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public License +# as published by the Free Software Foundation; either version 3 of +# the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public -# License for more details. +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. # -# You should have received a copy of the GNU Lesser General Public License -# along with this library; if not, write to the Free Software Foundation, -# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA # Test for %fast-slot-ref, which was previously implemented such that # an out-of-range slot index could escape being properly detected, and @@ -25,7 +26,7 @@ # executing the (%fast-slot-ref i 3) line. For reasons as yet # unknown, it does not cause a segmentation fault if the same code is # loaded as a script; that is why we run it here using "guile -q </dev/null 2>&1 </dev/null 2>&1 < () (a #:init-value 1) (b #:init-value 2) (c #:init-value 3)) diff --git a/test-suite/standalone/test-list.c b/test-suite/standalone/test-list.c index 02634f676..824463447 100644 --- a/test-suite/standalone/test-list.c +++ b/test-suite/standalone/test-list.c @@ -3,18 +3,19 @@ /* Copyright (C) 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ #ifndef HAVE_CONFIG_H diff --git a/test-suite/standalone/test-num2integral.c b/test-suite/standalone/test-num2integral.c index 1e8a016d5..8b69b071d 100644 --- a/test-suite/standalone/test-num2integral.c +++ b/test-suite/standalone/test-num2integral.c @@ -1,18 +1,19 @@ /* Copyright (C) 1999,2000,2001,2003,2004, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ #ifndef HAVE_CONFIG_H diff --git a/test-suite/standalone/test-round.c b/test-suite/standalone/test-round.c index 9725491c9..862e7d0fd 100644 --- a/test-suite/standalone/test-round.c +++ b/test-suite/standalone/test-round.c @@ -1,18 +1,19 @@ -/* Copyright (C) 2004, 2006, 2008 Free Software Foundation, Inc. +/* Copyright (C) 2004, 2006, 2008, 2009 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ #if HAVE_CONFIG_H @@ -25,6 +26,13 @@ #if HAVE_FENV_H #include +#elif defined HAVE_MACHINE_FPU_H +/* On Tru64 5.1b, the declaration of fesetround(3) is in . + On NetBSD, this header has to be included along with . */ +# ifdef HAVE_SYS_TYPES_H +# include +# endif +# include #endif #include diff --git a/test-suite/standalone/test-scm-c-read.c b/test-suite/standalone/test-scm-c-read.c index 1b4caa1c7..4111cd0f5 100644 --- a/test-suite/standalone/test-scm-c-read.c +++ b/test-suite/standalone/test-scm-c-read.c @@ -1,18 +1,19 @@ /* Copyright (C) 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ /* Exercise `scm_c_read ()' and the port type API. Verify assumptions that diff --git a/test-suite/standalone/test-scm-take-locale-symbol.c b/test-suite/standalone/test-scm-take-locale-symbol.c index 715f7f984..808068fbf 100644 --- a/test-suite/standalone/test-scm-take-locale-symbol.c +++ b/test-suite/standalone/test-scm-take-locale-symbol.c @@ -1,18 +1,19 @@ /* Copyright (C) 2009 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ /* Exercise `scm_take_locale_symbol ()', making sure it returns an interned diff --git a/test-suite/standalone/test-scm-with-guile.c b/test-suite/standalone/test-scm-with-guile.c index 7fe16b351..a78458e6c 100644 --- a/test-suite/standalone/test-scm-with-guile.c +++ b/test-suite/standalone/test-scm-with-guile.c @@ -1,18 +1,19 @@ /* Copyright (C) 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ diff --git a/test-suite/standalone/test-unwind.c b/test-suite/standalone/test-unwind.c index 472887abe..2b0291dd5 100644 --- a/test-suite/standalone/test-unwind.c +++ b/test-suite/standalone/test-unwind.c @@ -1,18 +1,19 @@ /* Copyright (C) 2004, 2005, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/test-suite/standalone/test-use-srfi.in b/test-suite/standalone/test-use-srfi.in index 57f84afe4..ab9d5cd5e 100755 --- a/test-suite/standalone/test-use-srfi.in +++ b/test-suite/standalone/test-use-srfi.in @@ -2,24 +2,25 @@ # Copyright (C) 2006 Free Software Foundation, Inc. # -# This library is free software; you can redistribute it and/or modify it -# under the terms of the GNU Lesser General Public License as published by -# the Free Software Foundation; either version 2.1 of the License, or (at -# your option) any later version. +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public License +# as published by the Free Software Foundation; either version 3 of +# the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public -# License for more details. +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. # -# You should have received a copy of the GNU Lesser General Public License -# along with this library; if not, write to the Free Software Foundation, -# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA # Test that two srfi numbers on the command line work. # -guile -q -l @top_builddir_absolute@/libguile/stack-limit-calibration.scm --use-srfi=1,10 >/dev/null </dev/null </dev/null </dev/null </dev/null </dev/null <u8-list sym val) + (let ((entry (assq-ref `((uint16 2 ,bytevector-u16-native-set!) + (uint32 4 ,bytevector-u32-native-set!)) + sym))) + (or entry (error "unknown sym" sym)) + (let ((bv (make-bytevector (car entry)))) + ((cadr entry) bv 0 val) + (bytevector->u8-list bv)))) + (define (munge-bytecode v) - (let ((newv (make-u8vector (vector-length v)))) - (let lp ((i 0)) - (if (= i (vector-length v)) - newv - (let ((x (vector-ref v i))) - (u8vector-set! newv i (if (symbol? x) - (instruction->opcode x) - x)) - (lp (1+ i))))))) + (let lp ((i 0) (out '())) + (if (= i (vector-length v)) + (list->u8vector (reverse out)) + (let ((x (vector-ref v i))) + (cond + ((symbol? x) + (lp (1+ i) (cons (instruction->opcode x) out))) + ((integer? x) + (lp (1+ i) (cons x out))) + ((pair? x) + (lp (1+ i) (append (reverse (apply ->u8-list x)) out))) + (else (error "bad test bytecode" x))))))) (define (comp-test x y) (let* ((y (munge-bytecode y)) @@ -45,21 +58,13 @@ (lambda () (equal? v y))))) + (with-test-prefix "compiler" (with-test-prefix "asm-to-bytecode" (comp-test '(make-int8 3) #(make-int8 3)) - (comp-test `(load-integer ,(string (integer->char 0))) - #(load-integer 0 0 1 0)) - - (comp-test `(load-integer ,(string (integer->char 255))) - #(load-integer 0 0 1 255)) - - (comp-test `(load-integer ,(string (integer->char 1) (integer->char 0))) - #(load-integer 0 0 2 1 0)) - (comp-test '(load-number "3.14") (vector 'load-number 0 0 4 (char->integer #\3) (char->integer #\.) (char->integer #\1) (char->integer #\4))) @@ -72,25 +77,34 @@ (vector 'load-symbol 0 0 3 (char->integer #\f) (char->integer #\o) (char->integer #\o))) - (comp-test '(load-keyword "qux") - (vector 'load-keyword 0 0 3 (char->integer #\q) (char->integer #\u) - (char->integer #\x))) - - ;; fixme: little-endian test. - (comp-test '(load-program 3 2 1 0 () 3 #f (make-int8 3) (return)) - (vector 'load-program 3 2 1 0 3 0 0 0 0 0 0 0 - (instruction->opcode 'make-int8) 3 - (instruction->opcode 'return))) + (comp-test '(load-program 3 2 1 () 3 #f (make-int8 3) (return)) + #(load-program + 3 2 (uint16 1) ;; nargs, nrest, nlocs + (uint32 3) ;; len + (uint32 0) ;; metalen + (uint32 0) ;; padding + make-int8 3 + return)) - ;; fixme: little-endian test. - (comp-test '(load-program 3 2 1 0 () 3 - (load-program 3 2 1 0 () 3 + ;; the nops are to pad meta to an 8-byte alignment. not strictly + ;; necessary for this test, but representative of the common case. + (comp-test '(load-program 3 2 1 () 8 + (load-program 3 2 1 () 3 #f (make-int8 3) (return)) - (make-int8 3) (return)) - (vector 'load-program 3 2 1 0 3 0 0 0 (+ 3 12) 0 0 0 - (instruction->opcode 'make-int8) 3 - (instruction->opcode 'return) - 3 2 1 0 3 0 0 0 0 0 0 0 - (instruction->opcode 'make-int8) 3 - (instruction->opcode 'return))))) + (make-int8 3) (return) + (nop) (nop) (nop) (nop) (nop)) + #(load-program + 3 2 (uint16 1) ;; nargs, nrest, nlocs + (uint32 8) ;; len + (uint32 19) ;; metalen + (uint32 0) ;; padding + make-int8 3 + return + nop nop nop nop nop + 3 2 (uint16 1) ;; nargs, nrest, nlocs + (uint32 3) ;; len + (uint32 0) ;; metalen + (uint32 0) ;; padding + make-int8 3 + return)))) diff --git a/test-suite/tests/bit-operations.test b/test-suite/tests/bit-operations.test index 8e35257b3..0e9df7d09 100644 --- a/test-suite/tests/bit-operations.test +++ b/test-suite/tests/bit-operations.test @@ -1,10 +1,10 @@ ;;;; bit-operations.test --- bitwise operations on numbers -*- scheme -*- -;;;; Copyright (C) 2000, 2001, 2003, 2006 Free Software Foundation, Inc. +;;;; Copyright (C) 2000, 2001, 2003, 2006, 2009 Free Software Foundation, Inc. ;;;; ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -15,8 +15,9 @@ ;;;; License along with this library; if not, write to the Free Software ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -(use-modules (test-suite lib) - (ice-9 documentation)) +(define-module (test-bit-operations) + :use-module (test-suite lib) + :use-module (ice-9 documentation)) ;;; diff --git a/test-suite/tests/bytevectors.test b/test-suite/tests/bytevectors.test new file mode 100644 index 000000000..8b336bb5b --- /dev/null +++ b/test-suite/tests/bytevectors.test @@ -0,0 +1,681 @@ +;;;; bytevectors.test --- Exercise the R6RS bytevector API. +;;;; +;;;; Copyright (C) 2009 Free Software Foundation, Inc. +;;;; Ludovic Courtès +;;;; +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +(define-module (test-bytevector) + :use-module (test-suite lib) + :use-module (system base compile) + :use-module (rnrs bytevector)) + +;;; Some of the tests in here are examples taken from the R6RS Standard +;;; Libraries document. + +(define-syntax c&e + (syntax-rules (pass-if pass-if-exception) + ((_ (pass-if test-name exp)) + (begin (pass-if (string-append test-name " (eval)") + (primitive-eval 'exp)) + (pass-if (string-append test-name " (compile)") + (compile 'exp #:to 'value)))) + ((_ (pass-if-exception test-name exc exp)) + (begin (pass-if-exception (string-append test-name " (eval)") + exc (primitive-eval 'exp)) + (pass-if-exception (string-append test-name " (compile)") + exc (compile 'exp #:to 'value)))))) + +(define-syntax with-test-prefix/c&e + (syntax-rules () + ((_ section-name exp ...) + (with-test-prefix section-name (c&e exp) ...)))) + + + +(with-test-prefix/c&e "2.2 General Operations" + + (pass-if "native-endianness" + (not (not (memq (native-endianness) '(big little))))) + + (pass-if "make-bytevector" + (and (bytevector? (make-bytevector 20)) + (bytevector? (make-bytevector 20 3)))) + + (pass-if "bytevector-length" + (= (bytevector-length (make-bytevector 20)) 20)) + + (pass-if "bytevector=?" + (and (bytevector=? (make-bytevector 20 7) + (make-bytevector 20 7)) + (not (bytevector=? (make-bytevector 20 7) + (make-bytevector 20 0)))))) + + +(with-test-prefix/c&e "2.3 Operations on Bytes and Octets" + + (pass-if "bytevector-{u8,s8}-ref" + (equal? '(-127 129 -1 255) + (let ((b1 (make-bytevector 16 -127)) + (b2 (make-bytevector 16 255))) + (list (bytevector-s8-ref b1 0) + (bytevector-u8-ref b1 0) + (bytevector-s8-ref b2 0) + (bytevector-u8-ref b2 0))))) + + (pass-if "bytevector-{u8,s8}-set!" + (equal? '(-126 130 -10 246) + (let ((b (make-bytevector 16 -127))) + + (bytevector-s8-set! b 0 -126) + (bytevector-u8-set! b 1 246) + + (list (bytevector-s8-ref b 0) + (bytevector-u8-ref b 0) + (bytevector-s8-ref b 1) + (bytevector-u8-ref b 1))))) + + (pass-if "bytevector->u8-list" + (let ((lst '(1 2 3 128 150 255))) + (equal? lst + (bytevector->u8-list + (let ((b (make-bytevector 6))) + (for-each (lambda (i v) + (bytevector-u8-set! b i v)) + (iota 6) + lst) + b))))) + + (pass-if "u8-list->bytevector" + (let ((lst '(1 2 3 128 150 255))) + (equal? lst + (bytevector->u8-list (u8-list->bytevector lst))))) + + (pass-if "bytevector-uint-{ref,set!} [small]" + (let ((b (make-bytevector 15))) + (bytevector-uint-set! b 0 #x1234 + (endianness little) 2) + (equal? (bytevector-uint-ref b 0 (endianness big) 2) + #x3412))) + + (pass-if "bytevector-uint-set! [large]" + (let ((b (make-bytevector 16))) + (bytevector-uint-set! b 0 (- (expt 2 128) 3) + (endianness little) 16) + (equal? (bytevector->u8-list b) + '(253 255 255 255 255 255 255 255 + 255 255 255 255 255 255 255 255)))) + + (pass-if "bytevector-uint-{ref,set!} [large]" + (let ((b (make-bytevector 120))) + (bytevector-uint-set! b 0 (- (expt 2 128) 3) + (endianness little) 16) + (equal? (bytevector-uint-ref b 0 (endianness little) 16) + #xfffffffffffffffffffffffffffffffd))) + + (pass-if "bytevector-sint-ref [small]" + (let ((b (u8-list->bytevector '(#xff #xf0 #xff)))) + (equal? (bytevector-sint-ref b 0 (endianness big) 2) + (bytevector-sint-ref b 1 (endianness little) 2) + -16))) + + (pass-if "bytevector-sint-ref [large]" + (let ((b (make-bytevector 50))) + (bytevector-uint-set! b 0 (- (expt 2 128) 3) + (endianness little) 16) + (equal? (bytevector-sint-ref b 0 (endianness little) 16) + -3))) + + (pass-if "bytevector-sint-set! [small]" + (let ((b (make-bytevector 3))) + (bytevector-sint-set! b 0 -16 (endianness big) 2) + (bytevector-sint-set! b 1 -16 (endianness little) 2) + (equal? (bytevector->u8-list b) + '(#xff #xf0 #xff)))) + + (pass-if "equal?" + (let ((bv1 (u8-list->bytevector (iota 123))) + (bv2 (u8-list->bytevector (iota 123)))) + (equal? bv1 bv2)))) + + +(with-test-prefix/c&e "2.4 Operations on Integers of Arbitrary Size" + + (pass-if "bytevector->sint-list" + (let ((b (u8-list->bytevector '(1 2 3 255 1 2 1 2)))) + (equal? (bytevector->sint-list b (endianness little) 2) + '(513 -253 513 513)))) + + (pass-if "bytevector->uint-list" + (let ((b (u8-list->bytevector '(2 1 255 3 2 1 2 1)))) + (equal? (bytevector->uint-list b (endianness big) 2) + '(513 65283 513 513)))) + + (pass-if "bytevector->uint-list [empty]" + (let ((b (make-bytevector 0))) + (null? (bytevector->uint-list b (endianness big) 2)))) + + (pass-if-exception "bytevector->sint-list [out-of-range]" + exception:out-of-range + (bytevector->sint-list (make-bytevector 6) (endianness little) 8)) + + (pass-if "bytevector->sint-list [off-by-one]" + (equal? (bytevector->sint-list (make-bytevector 31 #xff) + (endianness little) 8) + '(-1 -1 -1))) + + (pass-if "{sint,uint}-list->bytevector" + (let ((b1 (sint-list->bytevector '(513 -253 513 513) + (endianness little) 2)) + (b2 (uint-list->bytevector '(513 65283 513 513) + (endianness little) 2)) + (b3 (u8-list->bytevector '(1 2 3 255 1 2 1 2)))) + (and (bytevector=? b1 b2) + (bytevector=? b2 b3)))) + + (pass-if "sint-list->bytevector [limits]" + (bytevector=? (sint-list->bytevector '(-32768 32767) + (endianness big) 2) + (let ((bv (make-bytevector 4))) + (bytevector-u8-set! bv 0 #x80) + (bytevector-u8-set! bv 1 #x00) + (bytevector-u8-set! bv 2 #x7f) + (bytevector-u8-set! bv 3 #xff) + bv))) + + (pass-if-exception "sint-list->bytevector [out-of-range]" + exception:out-of-range + (sint-list->bytevector (list 0 0 (expt 2 16)) (endianness big) + 2)) + + (pass-if-exception "uint-list->bytevector [out-of-range]" + exception:out-of-range + (uint-list->bytevector '(0 -1) (endianness big) 2))) + + +(with-test-prefix/c&e "2.5 Operations on 16-Bit Integers" + + (pass-if "bytevector-u16-ref" + (let ((b (u8-list->bytevector + '(255 255 255 255 255 255 255 255 + 255 255 255 255 255 255 255 253)))) + (and (equal? (bytevector-u16-ref b 14 (endianness little)) + #xfdff) + (equal? (bytevector-u16-ref b 14 (endianness big)) + #xfffd)))) + + (pass-if "bytevector-s16-ref" + (let ((b (u8-list->bytevector + '(255 255 255 255 255 255 255 255 + 255 255 255 255 255 255 255 253)))) + (and (equal? (bytevector-s16-ref b 14 (endianness little)) + -513) + (equal? (bytevector-s16-ref b 14 (endianness big)) + -3)))) + + (pass-if "bytevector-s16-ref [unaligned]" + (let ((b (u8-list->bytevector '(#xff #xf0 #xff)))) + (equal? (bytevector-s16-ref b 1 (endianness little)) + -16))) + + (pass-if "bytevector-{u16,s16}-ref" + (let ((b (make-bytevector 2))) + (bytevector-u16-set! b 0 44444 (endianness little)) + (and (equal? (bytevector-u16-ref b 0 (endianness little)) + 44444) + (equal? (bytevector-s16-ref b 0 (endianness little)) + (- 44444 65536))))) + + (pass-if "bytevector-native-{u16,s16}-{ref,set!}" + (let ((b (make-bytevector 2))) + (bytevector-u16-native-set! b 0 44444) + (and (equal? (bytevector-u16-native-ref b 0) + 44444) + (equal? (bytevector-s16-native-ref b 0) + (- 44444 65536))))) + + (pass-if "bytevector-s16-{ref,set!} [unaligned]" + (let ((b (make-bytevector 3))) + (bytevector-s16-set! b 1 -77 (endianness little)) + (equal? (bytevector-s16-ref b 1 (endianness little)) + -77)))) + + +(with-test-prefix/c&e "2.6 Operations on 32-bit Integers" + + (pass-if "bytevector-u32-ref" + (let ((b (u8-list->bytevector + '(255 255 255 255 255 255 255 255 + 255 255 255 255 255 255 255 253)))) + (and (equal? (bytevector-u32-ref b 12 (endianness little)) + #xfdffffff) + (equal? (bytevector-u32-ref b 12 (endianness big)) + #xfffffffd)))) + + (pass-if "bytevector-s32-ref" + (let ((b (u8-list->bytevector + '(255 255 255 255 255 255 255 255 + 255 255 255 255 255 255 255 253)))) + (and (equal? (bytevector-s32-ref b 12 (endianness little)) + -33554433) + (equal? (bytevector-s32-ref b 12 (endianness big)) + -3)))) + + (pass-if "bytevector-{u32,s32}-ref" + (let ((b (make-bytevector 4))) + (bytevector-u32-set! b 0 2222222222 (endianness little)) + (and (equal? (bytevector-u32-ref b 0 (endianness little)) + 2222222222) + (equal? (bytevector-s32-ref b 0 (endianness little)) + (- 2222222222 (expt 2 32)))))) + + (pass-if "bytevector-{u32,s32}-native-{ref,set!}" + (let ((b (make-bytevector 4))) + (bytevector-u32-native-set! b 0 2222222222) + (and (equal? (bytevector-u32-native-ref b 0) + 2222222222) + (equal? (bytevector-s32-native-ref b 0) + (- 2222222222 (expt 2 32))))))) + + +(with-test-prefix/c&e "2.7 Operations on 64-bit Integers" + + (pass-if "bytevector-u64-ref" + (let ((b (u8-list->bytevector + '(255 255 255 255 255 255 255 255 + 255 255 255 255 255 255 255 253)))) + (and (equal? (bytevector-u64-ref b 8 (endianness little)) + #xfdffffffffffffff) + (equal? (bytevector-u64-ref b 8 (endianness big)) + #xfffffffffffffffd)))) + + (pass-if "bytevector-s64-ref" + (let ((b (u8-list->bytevector + '(255 255 255 255 255 255 255 255 + 255 255 255 255 255 255 255 253)))) + (and (equal? (bytevector-s64-ref b 8 (endianness little)) + -144115188075855873) + (equal? (bytevector-s64-ref b 8 (endianness big)) + -3)))) + + (pass-if "bytevector-{u64,s64}-ref" + (let ((b (make-bytevector 8)) + (big 9333333333333333333)) + (bytevector-u64-set! b 0 big (endianness little)) + (and (equal? (bytevector-u64-ref b 0 (endianness little)) + big) + (equal? (bytevector-s64-ref b 0 (endianness little)) + (- big (expt 2 64)))))) + + (pass-if "bytevector-{u64,s64}-native-{ref,set!}" + (let ((b (make-bytevector 8)) + (big 9333333333333333333)) + (bytevector-u64-native-set! b 0 big) + (and (equal? (bytevector-u64-native-ref b 0) + big) + (equal? (bytevector-s64-native-ref b 0) + (- big (expt 2 64)))))) + + (pass-if "ref/set! with zero" + (let ((b (make-bytevector 8))) + (bytevector-s64-set! b 0 -1 (endianness big)) + (bytevector-u64-set! b 0 0 (endianness big)) + (= 0 (bytevector-u64-ref b 0 (endianness big)))))) + + +(with-test-prefix/c&e "2.8 Operations on IEEE-754 Representations" + + (pass-if "bytevector-ieee-single-native-{ref,set!}" + (let ((b (make-bytevector 4)) + (number 3.00)) + (bytevector-ieee-single-native-set! b 0 number) + (equal? (bytevector-ieee-single-native-ref b 0) + number))) + + (pass-if "bytevector-ieee-single-{ref,set!}" + (let ((b (make-bytevector 8)) + (number 3.14)) + (bytevector-ieee-single-set! b 0 number (endianness little)) + (bytevector-ieee-single-set! b 4 number (endianness big)) + (equal? (bytevector-ieee-single-ref b 0 (endianness little)) + (bytevector-ieee-single-ref b 4 (endianness big))))) + + (pass-if "bytevector-ieee-single-{ref,set!} [unaligned]" + (let ((b (make-bytevector 9)) + (number 3.14)) + (bytevector-ieee-single-set! b 1 number (endianness little)) + (bytevector-ieee-single-set! b 5 number (endianness big)) + (equal? (bytevector-ieee-single-ref b 1 (endianness little)) + (bytevector-ieee-single-ref b 5 (endianness big))))) + + (pass-if "bytevector-ieee-double-native-{ref,set!}" + (let ((b (make-bytevector 8)) + (number 3.14)) + (bytevector-ieee-double-native-set! b 0 number) + (equal? (bytevector-ieee-double-native-ref b 0) + number))) + + (pass-if "bytevector-ieee-double-{ref,set!}" + (let ((b (make-bytevector 16)) + (number 3.14)) + (bytevector-ieee-double-set! b 0 number (endianness little)) + (bytevector-ieee-double-set! b 8 number (endianness big)) + (equal? (bytevector-ieee-double-ref b 0 (endianness little)) + (bytevector-ieee-double-ref b 8 (endianness big)))))) + + +(define (with-locale locale thunk) + ;; Run THUNK under LOCALE. + (let ((original-locale (setlocale LC_ALL))) + (catch 'system-error + (lambda () + (setlocale LC_ALL locale)) + (lambda (key . args) + (throw 'unresolved))) + + (dynamic-wind + (lambda () + #t) + thunk + (lambda () + (setlocale LC_ALL original-locale))))) + +(define (with-latin1-locale thunk) + ;; Try out several ISO-8859-1 locales and run THUNK under the one that + ;; works (if any). + (define %locales + (map (lambda (name) + (string-append name ".ISO-8859-1")) + '("fr_FR" "es_ES" "en_GB" "en_US" "de_DE" "pt_PT"))) + + (let loop ((locales %locales)) + (if (null? locales) + (throw 'unresolved) + (catch 'unresolved + (lambda () + (with-locale (car locales) thunk)) + (lambda (key . args) + (loop (cdr locales))))))) + + +;; Default to the C locale for the following tests. +(setlocale LC_ALL "C") + + +(with-test-prefix "2.9 Operations on Strings" + + (pass-if "string->utf8" + (let* ((str "hello, world") + (utf8 (string->utf8 str))) + (and (bytevector? utf8) + (= (bytevector-length utf8) + (string-length str)) + (equal? (string->list str) + (map integer->char (bytevector->u8-list utf8)))))) + + (pass-if "string->utf8 [latin-1]" + (with-latin1-locale + (lambda () + (let* ((str "hé, ça va bien ?") + (utf8 (string->utf8 str))) + (and (bytevector? utf8) + (= (bytevector-length utf8) + (+ 2 (string-length str)))))))) + + (pass-if "string->utf16" + (let* ((str "hello, world") + (utf16 (string->utf16 str))) + (and (bytevector? utf16) + (= (bytevector-length utf16) + (* 2 (string-length str))) + (equal? (string->list str) + (map integer->char + (bytevector->uint-list utf16 + (endianness big) 2)))))) + + (pass-if "string->utf16 [little]" + (let* ((str "hello, world") + (utf16 (string->utf16 str (endianness little)))) + (and (bytevector? utf16) + (= (bytevector-length utf16) + (* 2 (string-length str))) + (equal? (string->list str) + (map integer->char + (bytevector->uint-list utf16 + (endianness little) 2)))))) + + + (pass-if "string->utf32" + (let* ((str "hello, world") + (utf32 (string->utf32 str))) + (and (bytevector? utf32) + (= (bytevector-length utf32) + (* 4 (string-length str))) + (equal? (string->list str) + (map integer->char + (bytevector->uint-list utf32 + (endianness big) 4)))))) + + (pass-if "string->utf32 [little]" + (let* ((str "hello, world") + (utf32 (string->utf32 str (endianness little)))) + (and (bytevector? utf32) + (= (bytevector-length utf32) + (* 4 (string-length str))) + (equal? (string->list str) + (map integer->char + (bytevector->uint-list utf32 + (endianness little) 4)))))) + + (pass-if "utf8->string" + (let* ((utf8 (u8-list->bytevector (map char->integer + (string->list "hello, world")))) + (str (utf8->string utf8))) + (and (string? str) + (= (string-length str) + (bytevector-length utf8)) + (equal? (string->list str) + (map integer->char (bytevector->u8-list utf8)))))) + + (pass-if "utf8->string [latin-1]" + (with-latin1-locale + (lambda () + (let* ((utf8 (string->utf8 "hé, ça va bien ?")) + (str (utf8->string utf8))) + (and (string? str) + (= (string-length str) + (- (bytevector-length utf8) 2))))))) + + (pass-if "utf16->string" + (let* ((utf16 (uint-list->bytevector (map char->integer + (string->list "hello, world")) + (endianness big) 2)) + (str (utf16->string utf16))) + (and (string? str) + (= (* 2 (string-length str)) + (bytevector-length utf16)) + (equal? (string->list str) + (map integer->char + (bytevector->uint-list utf16 (endianness big) + 2)))))) + + (pass-if "utf16->string [little]" + (let* ((utf16 (uint-list->bytevector (map char->integer + (string->list "hello, world")) + (endianness little) 2)) + (str (utf16->string utf16 (endianness little)))) + (and (string? str) + (= (* 2 (string-length str)) + (bytevector-length utf16)) + (equal? (string->list str) + (map integer->char + (bytevector->uint-list utf16 (endianness little) + 2)))))) + (pass-if "utf32->string" + (let* ((utf32 (uint-list->bytevector (map char->integer + (string->list "hello, world")) + (endianness big) 4)) + (str (utf32->string utf32))) + (and (string? str) + (= (* 4 (string-length str)) + (bytevector-length utf32)) + (equal? (string->list str) + (map integer->char + (bytevector->uint-list utf32 (endianness big) + 4)))))) + + (pass-if "utf32->string [little]" + (let* ((utf32 (uint-list->bytevector (map char->integer + (string->list "hello, world")) + (endianness little) 4)) + (str (utf32->string utf32 (endianness little)))) + (and (string? str) + (= (* 4 (string-length str)) + (bytevector-length utf32)) + (equal? (string->list str) + (map integer->char + (bytevector->uint-list utf32 (endianness little) + 4))))))) + + + +(with-test-prefix "Datum Syntax" + + (pass-if "empty" + (equal? (with-input-from-string "#vu8()" read) + (make-bytevector 0))) + + (pass-if "simple" + (equal? (with-input-from-string "#vu8(1 2 3 4 5)" read) + (u8-list->bytevector '(1 2 3 4 5)))) + + (pass-if ">127" + (equal? (with-input-from-string "#vu8(0 255 127 128)" read) + (u8-list->bytevector '(0 255 127 128)))) + + (pass-if "self-evaluating" + (equal? (eval (with-input-from-string "#vu8(1 2 3 4 5)" read) + (current-module)) + (u8-list->bytevector '(1 2 3 4 5)))) + + (pass-if "quoted" + (equal? (eval (with-input-from-string "'#vu8(1 2 3 4 5)" read) + (current-module)) + (u8-list->bytevector '(1 2 3 4 5)))) + + (pass-if "literal simple" + (equal? #vu8(1 2 3 4 5) + (u8-list->bytevector '(1 2 3 4 5)))) + + (pass-if "literal >127" + (equal? #vu8(0 255 127 128) + (u8-list->bytevector '(0 255 127 128)))) + + (pass-if "literal quoted" + (equal? '#vu8(1 2 3 4 5) + (u8-list->bytevector '(1 2 3 4 5)))) + + (pass-if-exception "incorrect prefix" + exception:read-error + (with-input-from-string "#vi8(1 2 3)" read)) + + (pass-if-exception "extraneous space" + exception:read-error + (with-input-from-string "#vu8 (1 2 3)" read)) + + (pass-if-exception "negative integers" + exception:wrong-type-arg + (with-input-from-string "#vu8(-1 -2 -3)" read)) + + (pass-if-exception "out-of-range integers" + exception:wrong-type-arg + (with-input-from-string "#vu8(0 256)" read))) + + +(with-test-prefix "Generalized Vectors" + + (pass-if "generalized-vector?" + (generalized-vector? #vu8(1 2 3))) + + (pass-if "generalized-vector-length" + (equal? (iota 16) + (map generalized-vector-length + (map make-bytevector (iota 16))))) + + (pass-if "generalized-vector-ref" + (let ((bv #vu8(255 127))) + (and (= 255 (generalized-vector-ref bv 0)) + (= 127 (generalized-vector-ref bv 1))))) + + (pass-if-exception "generalized-vector-ref [index out-of-range]" + exception:out-of-range + (let ((bv #vu8(1 2))) + (generalized-vector-ref bv 2))) + + (pass-if "generalized-vector-set!" + (let ((bv (make-bytevector 2))) + (generalized-vector-set! bv 0 255) + (generalized-vector-set! bv 1 77) + (equal? '(255 77) + (bytevector->u8-list bv)))) + + (pass-if-exception "generalized-vector-set! [index out-of-range]" + exception:out-of-range + (let ((bv (make-bytevector 2))) + (generalized-vector-set! bv 2 0))) + + (pass-if-exception "generalized-vector-set! [value out-of-range]" + exception:out-of-range + (let ((bv (make-bytevector 2))) + (generalized-vector-set! bv 0 256))) + + (pass-if "array-type" + (eq? 'vu8 (array-type #vu8()))) + + (pass-if "array-contents" + (let ((bv (u8-list->bytevector (iota 10)))) + (eq? bv (array-contents bv)))) + + (pass-if "array-ref" + (let ((bv (u8-list->bytevector (iota 10)))) + (equal? (iota 10) + (map (lambda (i) (array-ref bv i)) + (iota 10))))) + + (pass-if "array-set!" + (let ((bv (make-bytevector 10))) + (for-each (lambda (i) + (array-set! bv i i)) + (iota 10)) + (equal? (iota 10) + (bytevector->u8-list bv)))) + + (pass-if "make-typed-array" + (let ((bv (make-typed-array 'vu8 77 33))) + (equal? bv (u8-list->bytevector (make-list 33 77))))) + + (pass-if-exception "make-typed-array [out-of-range]" + exception:out-of-range + (make-typed-array 'vu8 256 77)) + + (pass-if "uniform-array->bytevector" + (let ((bv #vu8(0 1 128 255))) + (equal? bv (uniform-array->bytevector bv))))) + + +;;; Local Variables: +;;; coding: latin-1 +;;; mode: scheme +;;; End: diff --git a/test-suite/tests/c-api.test b/test-suite/tests/c-api.test index 4a165d4cb..7c1b3bbd1 100644 --- a/test-suite/tests/c-api.test +++ b/test-suite/tests/c-api.test @@ -3,20 +3,19 @@ ;;;; ;;;; Copyright (C) 1999, 2006 Free Software Foundation, Inc. ;;;; -;;;; 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 2, or (at your option) -;;;; any later version. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. ;;;; -;;;; This program is distributed in the hope that it will be useful, +;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;;; GNU General Public License for more details. +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. ;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this software; see the file COPYING. If not, write to -;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;;; Boston, MA 02110-1301 USA +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (define srcdir (cdr (assq 'srcdir %guile-build-info))) diff --git a/test-suite/tests/chars.test b/test-suite/tests/chars.test index f14c832dd..b52b384c5 100644 --- a/test-suite/tests/chars.test +++ b/test-suite/tests/chars.test @@ -3,21 +3,19 @@ ;;;; ;;;; Copyright (C) 2000, 2006 Free Software Foundation, Inc. ;;;; -;;;; 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 2, or (at your option) -;;;; any later version. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. ;;;; -;;;; This program is distributed in the hope that it will be useful, +;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;;; GNU General Public License for more details. +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. ;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this software; see the file COPYING. If not, write to -;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;;; Boston, MA 02110-1301 USA - +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (use-modules (test-suite lib)) diff --git a/test-suite/tests/common-list.test b/test-suite/tests/common-list.test index c6f659b1e..dae806844 100644 --- a/test-suite/tests/common-list.test +++ b/test-suite/tests/common-list.test @@ -4,7 +4,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/test-suite/tests/compiler.test b/test-suite/tests/compiler.test index d83167f34..f9fabd7bc 100644 --- a/test-suite/tests/compiler.test +++ b/test-suite/tests/compiler.test @@ -1,10 +1,10 @@ ;;;; compiler.test --- tests for the compiler -*- scheme -*- -;;;; Copyright (C) 1991, 1992, 1993, 1994, 1995, 1999, 2001, 2006 Free Software Foundation, Inc. +;;;; Copyright (C) 2008, 2009 Free Software Foundation, Inc. ;;;; ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -18,45 +18,38 @@ (define-module (test-suite tests compiler) :use-module (test-suite lib) :use-module (test-suite guile-test) - :use-module (system vm program)) - + :use-module (system base compile)) -(with-test-prefix "environments" - (pass-if "compile-time-environment in evaluator" - (eq? (primitive-eval '(compile-time-environment)) #f)) + +(with-test-prefix "basic" - (pass-if "compile-time-environment in compiler" - (equal? (compile '(compile-time-environment)) - (cons (current-module) - (cons '() '())))) + (pass-if "compile to value" + (equal? (compile 1) 1))) - (let ((env (compile - '(let ((x 0)) (set! x 1) (compile-time-environment))))) - (pass-if "compile-time-environment in compiler, heap-allocated var" - (equal? env - (cons (current-module) - (cons '((x . 0)) '(1))))) + +(with-test-prefix "psyntax" - ;; fixme: compiling with #t or module - (pass-if "recompiling with environment" - (equal? ((compile '(lambda () x) #:env env)) - 1)) + (pass-if "redefinition" + ;; In this case the locally-bound `round' must have the same value as the + ;; imported `round'. See the same test in `syntax.test' for details. + (begin + (compile '(define round round)) + (compile '(eq? round (@@ (guile) round))))) - (pass-if "recompiling with environment/2" - (equal? ((compile '(lambda () (set! x (1+ x)) x) #:env env)) - 2)) + (pass-if "compile in current module" + (let ((o (begin + (compile '(define-macro (foo) 'bar)) + (compile '(let ((bar 'ok)) (foo)))))) + (and (module-ref (current-module) 'foo) + (eq? o 'ok)))) - (pass-if "recompiling with environment/3" - (equal? ((compile '(lambda () x) #:env env)) - 2)) - ) - - (pass-if "compile environment is #f" - (equal? ((compile '(lambda () 10))) - 10)) - - (pass-if "compile environment is a module" - (equal? ((compile '(lambda () 10) #:env (current-module))) - 10)) - ) \ No newline at end of file + (pass-if "compile in fresh module" + (let* ((m (let ((m (make-module))) + (beautify-user-module! m) + m)) + (o (begin + (compile '(define-macro (foo) 'bar) #:env m) + (compile '(let ((bar 'ok)) (foo)) #:env m)))) + (and (module-ref m 'foo) + (eq? o 'ok))))) diff --git a/test-suite/tests/continuations.test b/test-suite/tests/continuations.test index 7d76b762b..20a7a5ac1 100644 --- a/test-suite/tests/continuations.test +++ b/test-suite/tests/continuations.test @@ -3,20 +3,19 @@ ;;;; ;;;; Copyright (C) 2003, 2006 Free Software Foundation, Inc. ;;;; -;;;; 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 2, or (at your option) -;;;; any later version. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. ;;;; -;;;; This program is distributed in the hope that it will be useful, +;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;;; GNU General Public License for more details. +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. ;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this software; see the file COPYING. If not, write to -;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;;; Boston, MA 02110-1301 USA +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (define-module (test-suite test-continuations) :use-module (test-suite lib)) diff --git a/test-suite/tests/dynamic-scope.test b/test-suite/tests/dynamic-scope.test index d7a06a411..77be3b480 100644 --- a/test-suite/tests/dynamic-scope.test +++ b/test-suite/tests/dynamic-scope.test @@ -3,20 +3,19 @@ ;;;; ;;;; Copyright (C) 2001, 2006 Free Software Foundation, Inc. ;;;; -;;;; 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 2, or (at your option) -;;;; any later version. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. ;;;; -;;;; This program is distributed in the hope that it will be useful, +;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;;; GNU General Public License for more details. +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. ;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this software; see the file COPYING. If not, write to -;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;;; Boston, MA 02110-1301 USA +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (define-module (test-suite test-dynamic-scope) :use-module (test-suite lib)) diff --git a/test-suite/tests/elisp.test b/test-suite/tests/elisp.test index eaf6dbbff..fd028dac6 100644 --- a/test-suite/tests/elisp.test +++ b/test-suite/tests/elisp.test @@ -4,7 +4,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -23,6 +23,9 @@ (if *old-stack-level* (debug-set! stack (* 2 *old-stack-level*))) +(define *old-%load-should-autocompile* %load-should-autocompile) +(set! %load-should-autocompile #f) + ;;; ;;; elisp ;;; @@ -350,6 +353,7 @@ )) +(set! %load-should-autocompile *old-%load-should-autocompile*) (debug-set! stack *old-stack-level*) ;;; elisp.test ends here diff --git a/test-suite/tests/environments.nottest b/test-suite/tests/environments.nottest index 46883849a..90ef80f63 100644 --- a/test-suite/tests/environments.nottest +++ b/test-suite/tests/environments.nottest @@ -4,7 +4,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/test-suite/tests/eval.test b/test-suite/tests/eval.test index 7a22f0dff..47d7ca99f 100644 --- a/test-suite/tests/eval.test +++ b/test-suite/tests/eval.test @@ -4,7 +4,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -24,6 +24,9 @@ (define exception:bad-expression (cons 'syntax-error "Bad expression")) +(define exception:failed-match + (cons 'syntax-error "failed to match any pattern")) + ;;; ;;; miscellaneous @@ -85,17 +88,19 @@ ;; Macros are accepted as function parameters. ;; Functions that 'apply' macros are rewritten!!! - (expect-fail-exception "macro as argument" - exception:wrong-type-arg - (let ((f (lambda (p a b) (p a b)))) - (f and #t #t))) + (pass-if-exception "macro as argument" + exception:failed-match + (primitive-eval + '(let ((f (lambda (p a b) (p a b)))) + (f and #t #t)))) - (expect-fail-exception "passing macro as parameter" - exception:wrong-type-arg - (let* ((f (lambda (p a b) (p a b))) - (foo (procedure-source f))) - (f and #t #t) - (equal? (procedure-source f) foo))) + (pass-if-exception "passing macro as parameter" + exception:failed-match + (primitive-eval + '(let* ((f (lambda (p a b) (p a b))) + (foo (procedure-source f))) + (f and #t #t) + (equal? (procedure-source f) foo)))) )) diff --git a/test-suite/tests/exceptions.test b/test-suite/tests/exceptions.test index 4a9c1cb55..c2ec5f48d 100644 --- a/test-suite/tests/exceptions.test +++ b/test-suite/tests/exceptions.test @@ -4,7 +4,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/test-suite/tests/filesys.test b/test-suite/tests/filesys.test index b9913c2f2..a6bfb6eb5 100644 --- a/test-suite/tests/filesys.test +++ b/test-suite/tests/filesys.test @@ -5,7 +5,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/test-suite/tests/format.test b/test-suite/tests/format.test index cc3b6684b..04b31f138 100644 --- a/test-suite/tests/format.test +++ b/test-suite/tests/format.test @@ -3,20 +3,19 @@ ;;;; ;;;; Copyright (C) 2001, 2003, 2004, 2006 Free Software Foundation, Inc. ;;;; -;;;; 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 2, or (at your option) -;;;; any later version. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. ;;;; -;;;; This program is distributed in the hope that it will be useful, +;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;;; GNU General Public License for more details. +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. ;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this software; see the file COPYING. If not, write to -;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;;; Boston, MA 02110-1301 USA +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (define-module (test-format) #:use-module (test-suite lib) diff --git a/test-suite/tests/fractions.test b/test-suite/tests/fractions.test index 0e1a4d6c1..3ee1347d8 100644 --- a/test-suite/tests/fractions.test +++ b/test-suite/tests/fractions.test @@ -1,17 +1,18 @@ ;;;; Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc. ;;;; -;;;; This program is free software; you can redistribute it and/or modify -;;;; it under the terms of the GNU General Public License version 2 as -;;;; published by the Free Software Foundation; see file GNU-GPL. -;;;; -;;;; This program is distributed in the hope that it will be useful, +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;;; GNU General Public License for more details. -;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this program; if not, write to the Free Software Foundation, -;;;; Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;;;; Based in part on code from GNU CLISP, Copyright (C) 1993 Michael Stoll diff --git a/test-suite/tests/ftw.test b/test-suite/tests/ftw.test index c0cbb92cd..847fb9ff4 100644 --- a/test-suite/tests/ftw.test +++ b/test-suite/tests/ftw.test @@ -5,7 +5,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/test-suite/tests/gc.test b/test-suite/tests/gc.test index 407c4a286..063dad6d1 100644 --- a/test-suite/tests/gc.test +++ b/test-suite/tests/gc.test @@ -4,7 +4,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/test-suite/tests/getopt-long.test b/test-suite/tests/getopt-long.test index fe4a8872b..2c6f41515 100644 --- a/test-suite/tests/getopt-long.test +++ b/test-suite/tests/getopt-long.test @@ -3,20 +3,19 @@ ;;;; ;;;; Copyright (C) 2001, 2006 Free Software Foundation, Inc. ;;;; -;;;; 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 2, or (at your option) -;;;; any later version. -;;;; -;;;; This program is distributed in the hope that it will be useful, +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;;; GNU General Public License for more details. -;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this software; see the file COPYING. If not, write to -;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;;; Boston, MA 02110-1301 USA +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (use-modules (test-suite lib) (ice-9 getopt-long) diff --git a/test-suite/tests/goops.test b/test-suite/tests/goops.test index 2317228e4..c060d12a6 100644 --- a/test-suite/tests/goops.test +++ b/test-suite/tests/goops.test @@ -2,20 +2,19 @@ ;;;; ;;;; Copyright (C) 2001,2003,2004, 2006, 2008, 2009 Free Software Foundation, Inc. ;;;; -;;;; 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 2, or (at your option) -;;;; any later version. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. ;;;; -;;;; This program is distributed in the hope that it will be useful, +;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;;; GNU General Public License for more details. +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. ;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this software; see the file COPYING. If not, write to -;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;;; Boston, MA 02110-1301 USA +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (define-module (test-suite test-goops) #:use-module (test-suite lib) @@ -261,6 +260,19 @@ (method-more-specific? m1 m2 '())) (current-module)))) +(with-test-prefix "the method cache" + (pass-if "defining a method with a rest arg" + (let ((m (current-module))) + (eval '(define-method (foo bar . baz) + (cons bar baz)) + m) + (eval '(foo 1) + m) + (eval '(foo 1 2) + m) + (eval '(equal? (foo 1 2) '(1 2)) + m)))) + (with-test-prefix "defining accessors" (with-test-prefix "define-accessor" diff --git a/test-suite/tests/guardians.test b/test-suite/tests/guardians.test index 8e72d4106..470de4569 100644 --- a/test-suite/tests/guardians.test +++ b/test-suite/tests/guardians.test @@ -3,20 +3,19 @@ ;;;; ;;;; Copyright (C) 1999, 2001, 2006 Free Software Foundation, Inc. ;;;; -;;;; 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 2, or (at your option) -;;;; any later version. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. ;;;; -;;;; This program is distributed in the hope that it will be useful, +;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;;; GNU General Public License for more details. +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. ;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this software; see the file COPYING. If not, write to -;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;;; Boston, MA 02110-1301 USA +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; These tests make some questionable assumptions. ;;; diff --git a/test-suite/tests/hash.test b/test-suite/tests/hash.test index ccfd24ece..d2bde481c 100644 --- a/test-suite/tests/hash.test +++ b/test-suite/tests/hash.test @@ -5,7 +5,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/test-suite/tests/hooks.test b/test-suite/tests/hooks.test index f8ed39919..68c724704 100644 --- a/test-suite/tests/hooks.test +++ b/test-suite/tests/hooks.test @@ -4,7 +4,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/test-suite/tests/i18n.test b/test-suite/tests/i18n.test index 78d7e54fb..c4777c21c 100644 --- a/test-suite/tests/i18n.test +++ b/test-suite/tests/i18n.test @@ -6,13 +6,13 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. -;;;; +;;;; version 3 of the License, or (at your option) any later version. +;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;;;; Lesser General Public License for more details. -;;;; +;;;; ;;;; You should have received a copy of the GNU Lesser General Public ;;;; License along with this library; if not, write to the Free Software ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA diff --git a/test-suite/tests/import.test b/test-suite/tests/import.test index 4c4be02b2..1f2d26445 100644 --- a/test-suite/tests/import.test +++ b/test-suite/tests/import.test @@ -4,7 +4,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/test-suite/tests/interp.test b/test-suite/tests/interp.test index a091515b9..5f3e2aaf7 100644 --- a/test-suite/tests/interp.test +++ b/test-suite/tests/interp.test @@ -2,20 +2,19 @@ ;;;; ;;;; Copyright (C) 1999, 2001, 2006 Free Software Foundation, Inc. ;;;; -;;;; 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 2, or (at your option) -;;;; any later version. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. ;;;; -;;;; This program is distributed in the hope that it will be useful, +;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;;; GNU General Public License for more details. +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. ;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this software; see the file COPYING. If not, write to -;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;;; Boston, MA 02110-1301 USA +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (pass-if "Internal defines 1" (letrec ((foo (lambda (arg) diff --git a/test-suite/tests/list.test b/test-suite/tests/list.test index 7dc0ef0f8..d7b7801c9 100644 --- a/test-suite/tests/list.test +++ b/test-suite/tests/list.test @@ -4,7 +4,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/test-suite/tests/load.test b/test-suite/tests/load.test index a71a34716..59f9dbb61 100644 --- a/test-suite/tests/load.test +++ b/test-suite/tests/load.test @@ -3,20 +3,19 @@ ;;;; ;;;; Copyright (C) 1999, 2001, 2006 Free Software Foundation, Inc. ;;;; -;;;; 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 2, or (at your option) -;;;; any later version. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. ;;;; -;;;; This program is distributed in the hope that it will be useful, +;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;;; GNU General Public License for more details. +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. ;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this software; see the file COPYING. If not, write to -;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;;; Boston, MA 02110-1301 USA +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (define-module (test-suite test-load) :use-module (test-suite lib) diff --git a/test-suite/tests/modules.test b/test-suite/tests/modules.test index 43e35d8b7..f22cfe9c1 100644 --- a/test-suite/tests/modules.test +++ b/test-suite/tests/modules.test @@ -1,17 +1,17 @@ ;;;; modules.test --- exercise some of guile's module stuff -*- scheme -*- -;;;; Copyright (C) 2006, 2007 Free Software Foundation, Inc. +;;;; Copyright (C) 2006, 2007, 2009 Free Software Foundation, Inc. ;;;; ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. -;;;; +;;;; version 3 of the License, or (at your option) any later version. +;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;;;; Lesser General Public License for more details. -;;;; +;;;; ;;;; You should have received a copy of the GNU Lesser General Public ;;;; License along with this library; if not, write to the Free Software ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA @@ -34,6 +34,13 @@ (with-test-prefix "foundations" + (pass-if "modules don't remain anonymous" + ;; This is a requirement for `psyntax': it stores module names and relies + ;; on being able to `resolve-module' them. + (let ((m (make-module))) + (and (module-name m) + (eq? m (resolve-module (module-name m)))))) + (pass-if "module-add!" (let ((m (make-module)) (value (cons 'x 'y))) diff --git a/test-suite/tests/multilingual.nottest b/test-suite/tests/multilingual.nottest index 46a3ee2d3..cc911a108 100644 --- a/test-suite/tests/multilingual.nottest +++ b/test-suite/tests/multilingual.nottest @@ -4,20 +4,19 @@ ;;;; ;;;; Copyright (C) 1999, 2006 Free Software Foundation, Inc. ;;;; -;;;; 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 2, or (at your option) -;;;; any later version. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. ;;;; -;;;; This program is distributed in the hope that it will be useful, +;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;;; GNU General Public License for more details. +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. ;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this software; see the file COPYING. If not, write to -;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;;; Boston, MA 02110-1301 USA +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (use-modules (test-suite lib)) diff --git a/test-suite/tests/numbers.test b/test-suite/tests/numbers.test index 32627ed8c..4a9476a52 100644 --- a/test-suite/tests/numbers.test +++ b/test-suite/tests/numbers.test @@ -4,7 +4,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -1365,7 +1365,14 @@ ("1@0" 1.0) ("1@+0" 1.0) ("1@-0" 1.0) ("2+3i" ,(+ 2 (* 3 +i))) ("4-5i" ,(- 4 (* 5 +i))) ("1+i" 1+1i) ("1-i" 1-1i) ("+1i" 0+1i) ("-1i" 0-1i) - ("+i" +1i) ("-i" -1i))) + ("+i" +1i) ("-i" -1i) + ("1.0+.1i" 1.0+0.1i) + ("1.0-.1i" 1.0-0.1i) + (".1+.0i" 0.1) + ("1.+.0i" 1.0) + (".1+.1i" 0.1+0.1i) + ("1e1+.1i" 10+0.1i) + )) #t) (pass-if-exception "exponent too big" diff --git a/test-suite/tests/optargs.test b/test-suite/tests/optargs.test index 040b68ba4..5929ce909 100644 --- a/test-suite/tests/optargs.test +++ b/test-suite/tests/optargs.test @@ -3,20 +3,19 @@ ;;;; ;;;; Copyright (C) 2001, 2006 Free Software Foundation, Inc. ;;;; -;;;; 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 2, or (at your option) -;;;; any later version. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. ;;;; -;;;; This program is distributed in the hope that it will be useful, +;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;;; GNU General Public License for more details. +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. ;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this software; see the file COPYING. If not, write to -;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;;; Boston, MA 02110-1301 USA +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (define-module (test-suite test-optargs) :use-module (test-suite lib) diff --git a/test-suite/tests/options.test b/test-suite/tests/options.test index f2f87143b..a795109ce 100644 --- a/test-suite/tests/options.test +++ b/test-suite/tests/options.test @@ -2,20 +2,19 @@ ;;;; ;;;; Copyright (C) 2002, 2006 Free Software Foundation, Inc. ;;;; -;;;; 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 2, or (at your option) -;;;; any later version. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. ;;;; -;;;; This program is distributed in the hope that it will be useful, +;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;;; GNU General Public License for more details. +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. ;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this software; see the file COPYING. If not, write to -;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;;; Boston, MA 02110-1301 USA +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (use-modules (test-suite lib)) diff --git a/test-suite/tests/pairs.test b/test-suite/tests/pairs.test index af2f3e275..a317307b2 100644 --- a/test-suite/tests/pairs.test +++ b/test-suite/tests/pairs.test @@ -2,20 +2,19 @@ ;;;; ;;;; Copyright (C) 2003, 2006 Free Software Foundation, Inc. ;;;; -;;;; 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 2, or (at your option) -;;;; any later version. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. ;;;; -;;;; This program is distributed in the hope that it will be useful, +;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;;; GNU General Public License for more details. +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. ;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this software; see the file COPYING. If not, write to -;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;;; Boston, MA 02110-1301 USA +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (use-modules (test-suite lib)) diff --git a/test-suite/tests/poe.test b/test-suite/tests/poe.test index 6c7625602..707dc0272 100644 --- a/test-suite/tests/poe.test +++ b/test-suite/tests/poe.test @@ -5,7 +5,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/test-suite/tests/popen.test b/test-suite/tests/popen.test index 1dd2bc78e..0a20cff7a 100644 --- a/test-suite/tests/popen.test +++ b/test-suite/tests/popen.test @@ -5,7 +5,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -73,20 +73,46 @@ (open-input-pipe "echo hello")))))) #t) + (pass-if "open-input-pipe process gets (current-input-port) as stdin" + (let* ((p2c (pipe)) + (port (with-input-from-port (car p2c) + (lambda () + (open-input-pipe "read line && echo $line"))))) + (display "hello\n" (cdr p2c)) + (force-output (cdr p2c)) + (let ((result (eq? (read port) 'hello))) + (close-port (cdr p2c)) + (close-pipe port) + result))) + ;; After the child closes stdout (which it indicates here by writing - ;; "closed" to stderr), the parent should see eof. In Guile 1.6.4 and - ;; earlier a duplicate of stdout existed in the child, meaning eof was not - ;; seen. + ;; "closed" to stderr), the parent should see eof. In Guile 1.6.4 + ;; and earlier a duplicate of stdout existed in the child, meaning + ;; eof was not seen. + ;; + ;; Note that the objective here is to test that the parent sees EOF + ;; while the child is still alive. (It is obvious that the parent + ;; must see EOF once the child has died.) The use of the `p2c' + ;; pipe, and `echo closed' and `read' in the child, allows us to be + ;; sure that we are testing what the parent sees at a point where + ;; the child has closed stdout but is still alive. (pass-if "no duplicate" - (let* ((pair (pipe)) - (port (with-error-to-port (cdr pair) + (let* ((c2p (pipe)) + (p2c (pipe)) + (port (with-error-to-port (cdr c2p) (lambda () - (open-input-pipe - "exec 1>/dev/null; echo closed 1>&2; exec 2>/dev/null; sleep 999"))))) - (close-port (cdr pair)) ;; write side - (and (char? (read-char (car pair))) ;; wait for child to do its thing - (char-ready? port) - (eof-object? (read-char port)))))) + (with-input-from-port (car p2c) + (lambda () + (open-input-pipe + "exec 1>/dev/null; echo closed 1>&2; exec 2>/dev/null; read"))))))) + (close-port (cdr c2p)) ;; write side + (let ((result (eof-object? (read-char port)))) + (display "hello!\n" (cdr p2c)) + (force-output (cdr p2c)) + (close-pipe port) + result))) + + ) ;; ;; open-output-pipe @@ -121,27 +147,47 @@ #t) ;; After the child closes stdin (which it indicates here by writing - ;; "closed" to stderr), the parent should see a broken pipe. We setup to - ;; see this as EPIPE (rather than SIGPIPE). In Guile 1.6.4 and earlier a - ;; duplicate of stdin existed in the child, preventing the broken pipe - ;; occurring. + ;; "closed" to stderr), the parent should see a broken pipe. We + ;; setup to see this as EPIPE (rather than SIGPIPE). In Guile 1.6.4 + ;; and earlier a duplicate of stdin existed in the child, preventing + ;; the broken pipe occurring. + ;; + ;; Note that the objective here is to test that the parent sees a + ;; broken pipe while the child is still alive. (It is obvious that + ;; the parent will see a broken pipe once the child has died.) The + ;; use of the `c2p' pipe, and the repeated `echo closed' in the + ;; child, allows us to be sure that we are testing what the parent + ;; sees at a point where the child has closed stdin but is still + ;; alive. + ;; + ;; Note that `with-epipe' must apply only to the parent and not to + ;; the child process; we rely on the child getting SIGPIPE, to + ;; terminate it (and avoid leaving a zombie). (pass-if "no duplicate" - (with-epipe - (lambda () - (let* ((pair (pipe)) - (port (with-error-to-port (cdr pair) - (lambda () - (open-output-pipe - "exec 0&2; exec 2>/dev/null; sleep 999"))))) - (close-port (cdr pair)) ;; write side - (and (char? (read-char (car pair))) ;; wait for child to do its thing - (catch 'system-error - (lambda () - (write-char #\x port) - (force-output port) - #f) - (lambda (key name fmt args errno-list) - (= (car errno-list) EPIPE))))))))) + (let* ((c2p (pipe)) + (port (with-error-to-port (cdr c2p) + (lambda () + (open-output-pipe + "exec 0&2; done"))))) + (close-port (cdr c2p)) ;; write side + (with-epipe + (lambda () + (let ((result + (and (char? (read-char (car c2p))) ;; wait for child to do its thing + (catch 'system-error + (lambda () + (write-char #\x port) + (force-output port) + #f) + (lambda (key name fmt args errno-list) + (= (car errno-list) EPIPE)))))) + ;; Now close our reading end of the pipe. This should give + ;; the child a broken pipe and so allow it to exit. + (close-port (car c2p)) + (close-pipe port) + result))))) + + ) ;; ;; close-pipe diff --git a/test-suite/tests/ports.test b/test-suite/tests/ports.test index f1ba80be0..67df5b979 100644 --- a/test-suite/tests/ports.test +++ b/test-suite/tests/ports.test @@ -3,20 +3,19 @@ ;;;; ;;;; Copyright (C) 1999, 2001, 2004, 2006, 2007 Free Software Foundation, Inc. ;;;; -;;;; 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 2, or (at your option) -;;;; any later version. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. ;;;; -;;;; This program is distributed in the hope that it will be useful, +;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;;; GNU General Public License for more details. +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. ;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this software; see the file COPYING. If not, write to -;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;;; Boston, MA 02110-1301 USA +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (define-module (test-suite test-ports) :use-module (test-suite lib) diff --git a/test-suite/tests/posix.test b/test-suite/tests/posix.test index e93d1689f..06b70baa0 100644 --- a/test-suite/tests/posix.test +++ b/test-suite/tests/posix.test @@ -2,20 +2,19 @@ ;;;; ;;;; Copyright 2003, 2004, 2006, 2007 Free Software Foundation, Inc. ;;;; -;;;; 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 2, or (at your option) -;;;; any later version. -;;;; -;;;; This program is distributed in the hope that it will be useful, +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;;; GNU General Public License for more details. -;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this software; see the file COPYING. If not, write to -;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;;; Boston, MA 02110-1301 USA +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (define-module (test-suite test-posix) :use-module (test-suite lib)) diff --git a/test-suite/tests/procprop.test b/test-suite/tests/procprop.test index 40e89c792..5768e1a64 100644 --- a/test-suite/tests/procprop.test +++ b/test-suite/tests/procprop.test @@ -3,20 +3,19 @@ ;;;; ;;;; Copyright (C) 2009 Free Software Foundation, Inc. ;;;; -;;;; 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 2, or (at your option) -;;;; any later version. -;;;; -;;;; This program is distributed in the hope that it will be useful, +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;;; GNU General Public License for more details. -;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this software; see the file COPYING. If not, write to -;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;;; Boston, MA 02110-1301 USA +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (define-module (test-procpop) :use-module (test-suite lib)) diff --git a/test-suite/tests/q.test b/test-suite/tests/q.test index 5c24e5202..03f1bebe9 100644 --- a/test-suite/tests/q.test +++ b/test-suite/tests/q.test @@ -5,7 +5,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/test-suite/tests/r4rs.test b/test-suite/tests/r4rs.test index e47364c66..e26fdada3 100644 --- a/test-suite/tests/r4rs.test +++ b/test-suite/tests/r4rs.test @@ -4,7 +4,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/test-suite/tests/r5rs_pitfall.test b/test-suite/tests/r5rs_pitfall.test index 1357345b2..0bae630b5 100644 --- a/test-suite/tests/r5rs_pitfall.test +++ b/test-suite/tests/r5rs_pitfall.test @@ -4,7 +4,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/test-suite/tests/r6rs-ports.test b/test-suite/tests/r6rs-ports.test new file mode 100644 index 000000000..df12e5cbc --- /dev/null +++ b/test-suite/tests/r6rs-ports.test @@ -0,0 +1,456 @@ +;;;; r6rs-ports.test --- Exercise the R6RS I/O port API. +;;;; +;;;; Copyright (C) 2009 Free Software Foundation, Inc. +;;;; Ludovic Courtès +;;;; +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +(define-module (test-io-ports) + :use-module (test-suite lib) + :use-module (srfi srfi-1) + :use-module (srfi srfi-11) + :use-module (rnrs io ports) + :use-module (rnrs bytevector)) + +;;; All these tests assume Guile 1.8's port system, where characters are +;;; treated as octets. + + +(with-test-prefix "7.2.5 End-of-File Object" + + (pass-if "eof-object" + (and (eqv? (eof-object) (eof-object)) + (eq? (eof-object) (eof-object))))) + + +(with-test-prefix "7.2.8 Binary Input" + + (pass-if "get-u8" + (let ((port (open-input-string "A"))) + (and (= (char->integer #\A) (get-u8 port)) + (eof-object? (get-u8 port))))) + + (pass-if "lookahead-u8" + (let ((port (open-input-string "A"))) + (and (= (char->integer #\A) (lookahead-u8 port)) + (not (eof-object? port)) + (= (char->integer #\A) (get-u8 port)) + (eof-object? (get-u8 port))))) + + (pass-if "get-bytevector-n [short]" + (let* ((port (open-input-string "GNU Guile")) + (bv (get-bytevector-n port 4))) + (and (bytevector? bv) + (equal? (bytevector->u8-list bv) + (map char->integer (string->list "GNU ")))))) + + (pass-if "get-bytevector-n [long]" + (let* ((port (open-input-string "GNU Guile")) + (bv (get-bytevector-n port 256))) + (and (bytevector? bv) + (equal? (bytevector->u8-list bv) + (map char->integer (string->list "GNU Guile")))))) + + (pass-if-exception "get-bytevector-n with closed port" + exception:wrong-type-arg + + (let ((port (%make-void-port "r"))) + + (close-port port) + (get-bytevector-n port 3))) + + (pass-if "get-bytevector-n! [short]" + (let* ((port (open-input-string "GNU Guile")) + (bv (make-bytevector 4)) + (read (get-bytevector-n! port bv 0 4))) + (and (equal? read 4) + (equal? (bytevector->u8-list bv) + (map char->integer (string->list "GNU ")))))) + + (pass-if "get-bytevector-n! [long]" + (let* ((str "GNU Guile") + (port (open-input-string str)) + (bv (make-bytevector 256)) + (read (get-bytevector-n! port bv 0 256))) + (and (equal? read (string-length str)) + (equal? (map (lambda (i) + (bytevector-u8-ref bv i)) + (iota read)) + (map char->integer (string->list str)))))) + + (pass-if "get-bytevector-some [simple]" + (let* ((str "GNU Guile") + (port (open-input-string str)) + (bv (get-bytevector-some port))) + (and (bytevector? bv) + (equal? (bytevector->u8-list bv) + (map char->integer (string->list str)))))) + + (pass-if "get-bytevector-some [only-some]" + (let* ((str "GNU Guile") + (index 0) + (port (make-soft-port + (vector #f #f #f + (lambda () + (if (>= index (string-length str)) + (eof-object) + (let ((c (string-ref str index))) + (set! index (+ index 1)) + c))) + (lambda () #t) + (lambda () + ;; Number of readily available octets: falls to + ;; zero after 4 octets have been read. + (- 4 (modulo index 5)))) + "r")) + (bv (get-bytevector-some port))) + (and (bytevector? bv) + (= index 4) + (= (bytevector-length bv) index) + (equal? (bytevector->u8-list bv) + (map char->integer (string->list "GNU ")))))) + + (pass-if "get-bytevector-all" + (let* ((str "GNU Guile") + (index 0) + (port (make-soft-port + (vector #f #f #f + (lambda () + (if (>= index (string-length str)) + (eof-object) + (let ((c (string-ref str index))) + (set! index (+ index 1)) + c))) + (lambda () #t) + (let ((cont? #f)) + (lambda () + ;; Number of readily available octets: falls to + ;; zero after 4 octets have been read and then + ;; starts again. + (let ((a (if cont? + (- (string-length str) index) + (- 4 (modulo index 5))))) + (if (= 0 a) (set! cont? #t)) + a)))) + "r")) + (bv (get-bytevector-all port))) + (and (bytevector? bv) + (= index (string-length str)) + (= (bytevector-length bv) (string-length str)) + (equal? (bytevector->u8-list bv) + (map char->integer (string->list str))))))) + + +(define (make-soft-output-port) + (let* ((bv (make-bytevector 1024)) + (read-index 0) + (write-index 0) + (write-char (lambda (chr) + (bytevector-u8-set! bv write-index + (char->integer chr)) + (set! write-index (+ 1 write-index))))) + (make-soft-port + (vector write-char + (lambda (str) ;; write-string + (for-each write-char (string->list str))) + (lambda () #t) ;; flush-output + (lambda () ;; read-char + (if (>= read-index (bytevector-length bv)) + (eof-object) + (let ((c (bytevector-u8-ref bv read-index))) + (set! read-index (+ read-index 1)) + (integer->char c)))) + (lambda () #t)) ;; close-port + "rw"))) + +(with-test-prefix "7.2.11 Binary Output" + + (pass-if "put-u8" + (let ((port (make-soft-output-port))) + (put-u8 port 77) + (equal? (get-u8 port) 77))) + + (pass-if "put-bytevector [2 args]" + (let ((port (make-soft-output-port)) + (bv (make-bytevector 256))) + (put-bytevector port bv) + (equal? (bytevector->u8-list bv) + (bytevector->u8-list + (get-bytevector-n port (bytevector-length bv)))))) + + (pass-if "put-bytevector [3 args]" + (let ((port (make-soft-output-port)) + (bv (make-bytevector 256)) + (start 10)) + (put-bytevector port bv start) + (equal? (drop (bytevector->u8-list bv) start) + (bytevector->u8-list + (get-bytevector-n port (- (bytevector-length bv) start)))))) + + (pass-if "put-bytevector [4 args]" + (let ((port (make-soft-output-port)) + (bv (make-bytevector 256)) + (start 10) + (count 77)) + (put-bytevector port bv start count) + (equal? (take (drop (bytevector->u8-list bv) start) count) + (bytevector->u8-list + (get-bytevector-n port count))))) + + (pass-if-exception "put-bytevector with closed port" + exception:wrong-type-arg + + (let* ((bv (make-bytevector 4)) + (port (%make-void-port "w"))) + + (close-port port) + (put-bytevector port bv)))) + + +(with-test-prefix "7.2.7 Input Ports" + + ;; This section appears here so that it can use the binary input + ;; primitives. + + (pass-if "open-bytevector-input-port [1 arg]" + (let* ((str "Hello Port!") + (bv (u8-list->bytevector (map char->integer + (string->list str)))) + (port (open-bytevector-input-port bv)) + (read-to-string + (lambda (port) + (let loop ((chr (read-char port)) + (result '())) + (if (eof-object? chr) + (apply string (reverse! result)) + (loop (read-char port) + (cons chr result))))))) + + (equal? (read-to-string port) str))) + + (pass-if-exception "bytevector-input-port is read-only" + exception:wrong-type-arg + + (let* ((str "Hello Port!") + (bv (u8-list->bytevector (map char->integer + (string->list str)))) + (port (open-bytevector-input-port bv #f))) + + (write "hello" port))) + + (pass-if "bytevector input port supports seeking" + (let* ((str "Hello Port!") + (bv (u8-list->bytevector (map char->integer + (string->list str)))) + (port (open-bytevector-input-port bv #f))) + + (and (port-has-port-position? port) + (= 0 (port-position port)) + (port-has-set-port-position!? port) + (begin + (set-port-position! port 6) + (= 6 (port-position port))) + (bytevector=? (get-bytevector-all port) + (u8-list->bytevector + (map char->integer (string->list "Port!"))))))) + + (pass-if-exception "make-custom-binary-input-port [wrong-num-args]" + exception:wrong-num-args + + ;; Prior to Guile-R6RS-Libs 0.2, the last 3 arguments were wrongfully + ;; optional. + (make-custom-binary-input-port "port" (lambda args #t))) + + (pass-if "make-custom-binary-input-port" + (let* ((source (make-bytevector 7777)) + (read! (let ((pos 0) + (len (bytevector-length source))) + (lambda (bv start count) + (let ((amount (min count (- len pos)))) + (if (> amount 0) + (bytevector-copy! source pos + bv start amount)) + (set! pos (+ pos amount)) + amount)))) + (port (make-custom-binary-input-port "the port" read! + #f #f #f))) + + (bytevector=? (get-bytevector-all port) source))) + + (pass-if "custom binary input port does not support `port-position'" + (let* ((str "Hello Port!") + (source (open-bytevector-input-port + (u8-list->bytevector + (map char->integer (string->list str))))) + (read! (lambda (bv start count) + (let ((r (get-bytevector-n! source bv start count))) + (if (eof-object? r) + 0 + r)))) + (port (make-custom-binary-input-port "the port" read! + #f #f #f))) + (not (or (port-has-port-position? port) + (port-has-set-port-position!? port))))) + + (pass-if "custom binary input port supports `port-position'" + (let* ((str "Hello Port!") + (source (open-bytevector-input-port + (u8-list->bytevector + (map char->integer (string->list str))))) + (read! (lambda (bv start count) + (let ((r (get-bytevector-n! source bv start count))) + (if (eof-object? r) + 0 + r)))) + (get-pos (lambda () + (port-position source))) + (set-pos! (lambda (pos) + (set-port-position! source pos))) + (port (make-custom-binary-input-port "the port" read! + get-pos set-pos! #f))) + + (and (port-has-port-position? port) + (= 0 (port-position port)) + (port-has-set-port-position!? port) + (begin + (set-port-position! port 6) + (= 6 (port-position port))) + (bytevector=? (get-bytevector-all port) + (u8-list->bytevector + (map char->integer (string->list "Port!"))))))) + + (pass-if "custom binary input port `close-proc' is called" + (let* ((closed? #f) + (read! (lambda (bv start count) 0)) + (get-pos (lambda () 0)) + (set-pos! (lambda (pos) #f)) + (close! (lambda () (set! closed? #t))) + (port (make-custom-binary-input-port "the port" read! + get-pos set-pos! + close!))) + + (close-port port) + (gc) ; Test for marking a closed port. + closed?))) + + +(with-test-prefix "8.2.10 Output ports" + + (pass-if "open-bytevector-output-port" + (let-values (((port get-content) + (open-bytevector-output-port #f))) + (let ((source (make-bytevector 7777))) + (put-bytevector port source) + (and (bytevector=? (get-content) source) + (bytevector=? (get-content) (make-bytevector 0)))))) + + (pass-if "open-bytevector-output-port [put-u8]" + (let-values (((port get-content) + (open-bytevector-output-port))) + (put-u8 port 77) + (and (bytevector=? (get-content) (make-bytevector 1 77)) + (bytevector=? (get-content) (make-bytevector 0))))) + + (pass-if "open-bytevector-output-port [display]" + (let-values (((port get-content) + (open-bytevector-output-port))) + (display "hello" port) + (and (bytevector=? (get-content) (string->utf8 "hello")) + (bytevector=? (get-content) (make-bytevector 0))))) + + (pass-if "bytevector output port supports `port-position'" + (let-values (((port get-content) + (open-bytevector-output-port))) + (let ((source (make-bytevector 7777)) + (overwrite (make-bytevector 33))) + (and (port-has-port-position? port) + (port-has-set-port-position!? port) + (begin + (put-bytevector port source) + (= (bytevector-length source) + (port-position port))) + (begin + (set-port-position! port 10) + (= 10 (port-position port))) + (begin + (put-bytevector port overwrite) + (bytevector-copy! overwrite 0 source 10 + (bytevector-length overwrite)) + (= (port-position port) + (+ 10 (bytevector-length overwrite)))) + (bytevector=? (get-content) source) + (bytevector=? (get-content) (make-bytevector 0)))))) + + (pass-if "make-custom-binary-output" + (let ((port (make-custom-binary-output-port "cbop" + (lambda (x y z) 0) + #f #f #f))) + (and (output-port? port) + (binary-port? port) + (not (port-has-port-position? port)) + (not (port-has-set-port-position!? port))))) + + (pass-if "make-custom-binary-output-port [partial writes]" + (let* ((source (uint-list->bytevector (iota 333) + (native-endianness) 2)) + (sink (make-bytevector (bytevector-length source))) + (sink-pos 0) + (eof? #f) + (write! (lambda (bv start count) + (if (= 0 count) + (begin + (set! eof? #t) + 0) + (let ((u8 (bytevector-u8-ref bv start))) + ;; Get one byte at a time. + (bytevector-u8-set! sink sink-pos u8) + (set! sink-pos (+ 1 sink-pos)) + 1)))) + (port (make-custom-binary-output-port "cbop" write! + #f #f #f))) + (put-bytevector port source) + (and (= sink-pos (bytevector-length source)) + (not eof?) + (bytevector=? sink source)))) + + (pass-if "make-custom-binary-output-port [full writes]" + (let* ((source (uint-list->bytevector (iota 333) + (native-endianness) 2)) + (sink (make-bytevector (bytevector-length source))) + (sink-pos 0) + (eof? #f) + (write! (lambda (bv start count) + (if (= 0 count) + (begin + (set! eof? #t) + 0) + (begin + (bytevector-copy! bv start + sink sink-pos + count) + (set! sink-pos (+ sink-pos count)) + count)))) + (port (make-custom-binary-output-port "cbop" write! + #f #f #f))) + (put-bytevector port source) + (and (= sink-pos (bytevector-length source)) + (not eof?) + (bytevector=? sink source))))) + + +;;; Local Variables: +;;; coding: latin-1 +;;; mode: scheme +;;; End: diff --git a/test-suite/tests/ramap.test b/test-suite/tests/ramap.test index d923bc1f2..948a77870 100644 --- a/test-suite/tests/ramap.test +++ b/test-suite/tests/ramap.test @@ -5,7 +5,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/test-suite/tests/reader.test b/test-suite/tests/reader.test index b068c716d..0eb851508 100644 --- a/test-suite/tests/reader.test +++ b/test-suite/tests/reader.test @@ -6,13 +6,13 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. -;;;; +;;;; version 3 of the License, or (at your option) any later version. +;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;;;; Lesser General Public License for more details. -;;;; +;;;; ;;;; You should have received a copy of the GNU Lesser General Public ;;;; License along with this library; if not, write to the Free Software ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA @@ -35,6 +35,8 @@ (cons 'read-error "end of file in string constant$")) (define exception:illegal-escape (cons 'read-error "illegal character in escape sequence: .*$")) +(define exception:missing-expression + (cons 'read-error "no expression after #;")) (define (read-string s) @@ -165,6 +167,11 @@ (with-read-options '(keywords postfix) (lambda () (read-string "keyword:"))))) + (pass-if "long postfix keywords" + (eq? #:keyword0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 + (with-read-options '(keywords postfix) + (lambda () + (read-string "keyword0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789:"))))) (pass-if "`:' is not a postfix keyword (per SRFI-88)" (eq? ': (with-read-options '(keywords postfix) @@ -189,3 +196,36 @@ (and (equal? (source-property sexp 'line) 0) (equal? (source-property sexp 'column) 0))))) +(with-test-prefix "#;" + (for-each + (lambda (pair) + (pass-if (car pair) + (equal? (with-input-from-string (car pair) read) (cdr pair)))) + + '(("#;foo 10". 10) + ("#;(10 20 30) foo" . foo) + ("#; (10 20 30) foo" . foo) + ("#;\n10\n20" . 20))) + + (pass-if "#;foo" + (eof-object? (with-input-from-string "#;foo" read))) + + (pass-if-exception "#;" + exception:missing-expression + (with-input-from-string "#;" read)) + (pass-if-exception "#;(" + exception:eof + (with-input-from-string "#;(" read))) + +(with-test-prefix "#'" + (for-each + (lambda (pair) + (pass-if (car pair) + (equal? (with-input-from-string (car pair) read) (cdr pair)))) + + '(("#'foo". (syntax foo)) + ("#`foo" . (quasisyntax foo)) + ("#,foo" . (unsyntax foo)) + ("#,@foo" . (unsyntax-splicing foo))))) + + diff --git a/test-suite/tests/receive.test b/test-suite/tests/receive.test index 4b55bdf9f..3fb4abe20 100644 --- a/test-suite/tests/receive.test +++ b/test-suite/tests/receive.test @@ -2,20 +2,19 @@ ;;;; ;;;; Copyright (C) 2004, 2006 Free Software Foundation, Inc. ;;;; -;;;; 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 2, or (at your option) -;;;; any later version. -;;;; -;;;; This program is distributed in the hope that it will be useful, +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;;; GNU General Public License for more details. -;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this software; see the file COPYING. If not, write to -;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;;; Boston, MA 02110-1301 USA +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (define-module (test-suite test-receive) #:use-module (test-suite lib) diff --git a/test-suite/tests/regexp.test b/test-suite/tests/regexp.test index 15f77a34c..730839970 100644 --- a/test-suite/tests/regexp.test +++ b/test-suite/tests/regexp.test @@ -3,20 +3,19 @@ ;;;; ;;;; Copyright (C) 1999, 2004, 2006, 2007, 2008 Free Software Foundation, Inc. ;;;; -;;;; 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 2, or (at your option) -;;;; any later version. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. ;;;; -;;;; This program is distributed in the hope that it will be useful, +;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;;; GNU General Public License for more details. +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. ;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this software; see the file COPYING. If not, write to -;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;;; Boston, MA 02110-1301 USA +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (define-module (test-suite test-regexp) #:use-module (test-suite lib) diff --git a/test-suite/tests/socket.test b/test-suite/tests/socket.test index 4bfc41557..7626ceebf 100644 --- a/test-suite/tests/socket.test +++ b/test-suite/tests/socket.test @@ -5,7 +5,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/test-suite/tests/sort.test b/test-suite/tests/sort.test index a49c04857..292836d88 100644 --- a/test-suite/tests/sort.test +++ b/test-suite/tests/sort.test @@ -1,20 +1,19 @@ ;;;; sort.test --- tests Guile's sort functions -*- scheme -*- ;;;; Copyright (C) 2003, 2006, 2007 Free Software Foundation, Inc. ;;;; -;;;; 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 2, or (at your option) -;;;; any later version. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. ;;;; -;;;; This program is distributed in the hope that it will be useful, +;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;;; GNU General Public License for more details. +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. ;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this software; see the file COPYING. If not, write to -;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;;; Boston, MA 02110-1301 USA +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (use-modules (test-suite lib)) diff --git a/test-suite/tests/srcprop.test b/test-suite/tests/srcprop.test index 5bfe68080..8ec298960 100644 --- a/test-suite/tests/srcprop.test +++ b/test-suite/tests/srcprop.test @@ -5,7 +5,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/test-suite/tests/srfi-1.test b/test-suite/tests/srfi-1.test index 4f2838744..c163e7b69 100644 --- a/test-suite/tests/srfi-1.test +++ b/test-suite/tests/srfi-1.test @@ -2,20 +2,19 @@ ;;;; ;;;; Copyright 2003, 2004, 2005, 2006, 2008 Free Software Foundation, Inc. ;;;; -;;;; 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 2, or (at your option) -;;;; any later version. -;;;; -;;;; This program is distributed in the hope that it will be useful, +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;;; GNU General Public License for more details. -;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this software; see the file COPYING. If not, write to -;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;;; Boston, MA 02110-1301 USA +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (define-module (test-srfi-1) #:use-module (test-suite lib) diff --git a/test-suite/tests/srfi-10.test b/test-suite/tests/srfi-10.test index 248c04ff7..ab3cb884e 100644 --- a/test-suite/tests/srfi-10.test +++ b/test-suite/tests/srfi-10.test @@ -3,20 +3,19 @@ ;;;; ;;;; Copyright (C) 2001, 2006 Free Software Foundation, Inc. ;;;; -;;;; 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 2, or (at your option) -;;;; any later version. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. ;;;; -;;;; This program is distributed in the hope that it will be useful, +;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;;; GNU General Public License for more details. +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. ;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this software; see the file COPYING. If not, write to -;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;;; Boston, MA 02110-1301 USA +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (use-modules (srfi srfi-10)) diff --git a/test-suite/tests/srfi-11.test b/test-suite/tests/srfi-11.test index ec2ed86c8..40563dc18 100644 --- a/test-suite/tests/srfi-11.test +++ b/test-suite/tests/srfi-11.test @@ -2,20 +2,19 @@ ;;;; ;;;; Copyright 2004, 2006 Free Software Foundation, Inc. ;;;; -;;;; 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 2, or (at your option) -;;;; any later version. -;;;; -;;;; This program is distributed in the hope that it will be useful, +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;;; GNU General Public License for more details. -;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this software; see the file COPYING. If not, write to -;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;;; Boston, MA 02110-1301 USA +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (define-module (test-suite test-srfi-11) #:use-module (test-suite lib) diff --git a/test-suite/tests/srfi-13.test b/test-suite/tests/srfi-13.test index 89759d0d3..9dbf5bf40 100644 --- a/test-suite/tests/srfi-13.test +++ b/test-suite/tests/srfi-13.test @@ -3,20 +3,19 @@ ;;;; ;;;; Copyright (C) 2001, 2004, 2005, 2006 Free Software Foundation, Inc. ;;;; -;;;; 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 2, or (at your option) -;;;; any later version. -;;;; -;;;; This program is distributed in the hope that it will be useful, +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;;; GNU General Public License for more details. -;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this software; see the file COPYING. If not, write to -;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;;; Boston, MA 02110-1301 USA +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (define-module (test-strings) #:use-module (test-suite lib) diff --git a/test-suite/tests/srfi-14.test b/test-suite/tests/srfi-14.test index fc6307149..8c678cdd5 100644 --- a/test-suite/tests/srfi-14.test +++ b/test-suite/tests/srfi-14.test @@ -3,20 +3,19 @@ ;;;; ;;;; Copyright (C) 2001, 2006 Free Software Foundation, Inc. ;;;; -;;;; 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 2, or (at your option) -;;;; any later version. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. ;;;; -;;;; This program is distributed in the hope that it will be useful, +;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;;; GNU General Public License for more details. +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. ;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this software; see the file COPYING. If not, write to -;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;;; Boston, MA 02110-1301 USA +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (define-module (test-suite test-srfi-14) :use-module (srfi srfi-14) diff --git a/test-suite/tests/srfi-17.test b/test-suite/tests/srfi-17.test index fbacb15a3..d9e0054ba 100644 --- a/test-suite/tests/srfi-17.test +++ b/test-suite/tests/srfi-17.test @@ -2,20 +2,19 @@ ;;;; ;;;; Copyright (C) 2001, 2003, 2005, 2006 Free Software Foundation, Inc. ;;;; -;;;; 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 2, or (at your option) -;;;; any later version. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. ;;;; -;;;; This program is distributed in the hope that it will be useful, +;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;;; GNU General Public License for more details. +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. ;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this software; see the file COPYING. If not, write to -;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;;; Boston, MA 02110-1301 USA +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (define-module (test-suite test-srfi-17) :use-module (test-suite lib) @@ -50,6 +49,9 @@ (define %some-variable #f) +(define exception:bad-quote + '(syntax-error . "quote: bad syntax")) + (with-test-prefix "set!" (with-test-prefix "target is not procedure with setter" @@ -59,7 +61,7 @@ (set! (symbol->string 'x) 1)) (pass-if-exception "(set! '#f 1)" - exception:bad-variable + exception:bad-quote (eval '(set! '#f 1) (interaction-environment)))) (with-test-prefix "target uses macro" @@ -72,7 +74,7 @@ ;; The `(quote x)' below used to be memoized as an infinite list before ;; Guile 1.8.3. (pass-if-exception "(set! 'x 1)" - exception:bad-variable + exception:bad-quote (eval '(set! 'x 1) (interaction-environment))))) ;; diff --git a/test-suite/tests/srfi-18.test b/test-suite/tests/srfi-18.test index fa309e6ce..b769ce1a2 100644 --- a/test-suite/tests/srfi-18.test +++ b/test-suite/tests/srfi-18.test @@ -3,26 +3,30 @@ ;;;; ;;;; Copyright (C) 2007, 2008 Free Software Foundation, Inc. ;;;; -;;;; 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 2, or (at your option) -;;;; any later version. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. ;;;; -;;;; This program is distributed in the hope that it will be useful, +;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;;; GNU General Public License for more details. +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. ;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this software; see the file COPYING. If not, write to -;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;;; Boston, MA 02110-1301 USA +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (define-module (test-suite test-srfi-18) #:use-module (test-suite lib)) -(and (provided? 'threads) - (use-modules (srfi srfi-18)) +;; two expressions so that the srfi-18 import is in effect for expansion +;; of the rest +(if (provided? 'threads) + (use-modules (srfi srfi-18))) + +(and + (provided? 'threads) (with-test-prefix "current-thread" diff --git a/test-suite/tests/srfi-19.test b/test-suite/tests/srfi-19.test index 259a88a4e..f48ce6286 100644 --- a/test-suite/tests/srfi-19.test +++ b/test-suite/tests/srfi-19.test @@ -3,20 +3,19 @@ ;;;; ;;;; Copyright (C) 2001, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. ;;;; -;;;; 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 2, or (at your option) -;;;; any later version. -;;;; -;;;; This program is distributed in the hope that it will be useful, +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;;; GNU General Public License for more details. -;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this software; see the file COPYING. If not, write to -;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;;; Boston, MA 02110-1301 USA +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;; SRFI-19 overrides current-date, so we have to do the test in a ;; separate module, or later tests will fail. diff --git a/test-suite/tests/srfi-31.test b/test-suite/tests/srfi-31.test index bd6977333..6d65ce2bc 100644 --- a/test-suite/tests/srfi-31.test +++ b/test-suite/tests/srfi-31.test @@ -5,7 +5,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -23,7 +23,7 @@ (with-test-prefix "rec special form" (pass-if-exception "bogus variable" '(misc-error . ".*") - (rec #:foo)) + (sc-expand '(rec #:foo))) (pass-if "rec expressions" (let ((ones-list (rec ones (cons 1 (delay ones))))) diff --git a/test-suite/tests/srfi-34.test b/test-suite/tests/srfi-34.test index 2195d9471..17864b642 100644 --- a/test-suite/tests/srfi-34.test +++ b/test-suite/tests/srfi-34.test @@ -2,20 +2,19 @@ ;;;; ;;;; Copyright (C) 2003, 2004, 2006, 2008 Free Software Foundation, Inc. ;;;; -;;;; 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 2, or (at your option) -;;;; any later version. -;;;; -;;;; This program is distributed in the hope that it will be useful, +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;;; GNU General Public License for more details. -;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this software; see the file COPYING. If not, write to -;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;;; Boston, MA 02110-1301 USA +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (define-module (test-suite test-srfi-34) :duplicates (last) ;; avoid warning about srfi-34 replacing `raise' diff --git a/test-suite/tests/srfi-35.test b/test-suite/tests/srfi-35.test index 83efd61d9..24ee60248 100644 --- a/test-suite/tests/srfi-35.test +++ b/test-suite/tests/srfi-35.test @@ -3,20 +3,19 @@ ;;;; ;;;; Copyright (C) 2007, 2008 Free Software Foundation, Inc. ;;;; -;;;; 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 2, or (at your option) -;;;; any later version. -;;;; -;;;; This program is distributed in the hope that it will be useful, +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;;; GNU General Public License for more details. -;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this software; see the file COPYING. If not, write to -;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;;; Boston, MA 02110-1301 USA +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (define-module (test-srfi-35) :use-module (test-suite lib) diff --git a/test-suite/tests/srfi-37.test b/test-suite/tests/srfi-37.test index d7745876d..1f739c5c5 100644 --- a/test-suite/tests/srfi-37.test +++ b/test-suite/tests/srfi-37.test @@ -2,20 +2,19 @@ ;;;; ;;;; Copyright (C) 2007, 2008 Free Software Foundation, Inc. ;;;; -;;;; 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 2, or (at your option) -;;;; any later version. -;;;; -;;;; This program is distributed in the hope that it will be useful, +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;;; GNU General Public License for more details. -;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this software; see the file COPYING. If not, write to -;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;;; Boston, MA 02110-1301 USA +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (define-module (test-srfi-37) #:use-module (test-suite lib) diff --git a/test-suite/tests/srfi-39.test b/test-suite/tests/srfi-39.test index 277a3c60d..0153e58b4 100644 --- a/test-suite/tests/srfi-39.test +++ b/test-suite/tests/srfi-39.test @@ -2,20 +2,19 @@ ;;;; ;;;; Copyright (C) 2004, 2005, 2006, 2008 Free Software Foundation, Inc. ;;;; -;;;; 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 2, or (at your option) -;;;; any later version. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. ;;;; -;;;; This program is distributed in the hope that it will be useful, +;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;;; GNU General Public License for more details. +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. ;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this software; see the file COPYING. If not, write to -;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;;; Boston, MA 02110-1301 USA +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (define-module (test-srfi-39) #:use-module (test-suite lib) diff --git a/test-suite/tests/srfi-4.test b/test-suite/tests/srfi-4.test index ee773a3f9..8a9d53a61 100644 --- a/test-suite/tests/srfi-4.test +++ b/test-suite/tests/srfi-4.test @@ -3,20 +3,19 @@ ;;;; ;;;; Copyright (C) 2001, 2006 Free Software Foundation, Inc. ;;;; -;;;; 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 2, or (at your option) -;;;; any later version. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. ;;;; -;;;; This program is distributed in the hope that it will be useful, +;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;;; GNU General Public License for more details. +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. ;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this software; see the file COPYING. If not, write to -;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;;; Boston, MA 02110-1301 USA +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (use-modules (srfi srfi-4) (test-suite lib)) diff --git a/test-suite/tests/srfi-6.test b/test-suite/tests/srfi-6.test index 217fc9f78..68fc70dff 100644 --- a/test-suite/tests/srfi-6.test +++ b/test-suite/tests/srfi-6.test @@ -2,20 +2,19 @@ ;;;; ;;;; Copyright (C) 2003, 2006 Free Software Foundation, Inc. ;;;; -;;;; 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 2, or (at your option) -;;;; any later version. -;;;; -;;;; This program is distributed in the hope that it will be useful, +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;;; GNU General Public License for more details. -;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this software; see the file COPYING. If not, write to -;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;;; Boston, MA 02110-1301 USA +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (use-modules (test-suite lib)) diff --git a/test-suite/tests/srfi-60.test b/test-suite/tests/srfi-60.test index fff89f1ca..940934f3e 100644 --- a/test-suite/tests/srfi-60.test +++ b/test-suite/tests/srfi-60.test @@ -2,20 +2,19 @@ ;;;; ;;;; Copyright 2005, 2006 Free Software Foundation, Inc. ;;;; -;;;; 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 2, or (at your option) -;;;; any later version. -;;;; -;;;; This program is distributed in the hope that it will be useful, +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;;; GNU General Public License for more details. -;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this software; see the file COPYING. If not, write to -;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;;; Boston, MA 02110-1301 USA +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (define-module (test-srfi-60) #:duplicates (last) ;; avoid warning about srfi-60 replacing `bit-count' diff --git a/test-suite/tests/srfi-69.test b/test-suite/tests/srfi-69.test index 1d240d28c..e99b76c6d 100644 --- a/test-suite/tests/srfi-69.test +++ b/test-suite/tests/srfi-69.test @@ -2,20 +2,19 @@ ;;;; ;;;; Copyright (C) 2007 Free Software Foundation, Inc. ;;;; -;;;; 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 2, or (at your option) -;;;; any later version. -;;;; -;;;; This program is distributed in the hope that it will be useful, +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;;; GNU General Public License for more details. -;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this software; see the file COPYING. If not, write to -;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;;; Boston, MA 02110-1301 USA +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (define-module (test-srfi-69) #:use-module (test-suite lib) diff --git a/test-suite/tests/srfi-88.test b/test-suite/tests/srfi-88.test index 63f40cc40..b879941b2 100644 --- a/test-suite/tests/srfi-88.test +++ b/test-suite/tests/srfi-88.test @@ -3,20 +3,19 @@ ;;;; ;;;; Copyright (C) 2008 Free Software Foundation, Inc. ;;;; -;;;; 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 2, or (at your option) -;;;; any later version. -;;;; -;;;; This program is distributed in the hope that it will be useful, +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;;; GNU General Public License for more details. -;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this software; see the file COPYING. If not, write to -;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;;; Boston, MA 02110-1301 USA +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (define-module (test-srfi-88) :use-module (test-suite lib) diff --git a/test-suite/tests/srfi-9.test b/test-suite/tests/srfi-9.test index c212ea6aa..f8cb0b491 100644 --- a/test-suite/tests/srfi-9.test +++ b/test-suite/tests/srfi-9.test @@ -3,20 +3,19 @@ ;;;; ;;;; Copyright (C) 2001, 2006, 2007 Free Software Foundation, Inc. ;;;; -;;;; 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 2, or (at your option) -;;;; any later version. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. ;;;; -;;;; This program is distributed in the hope that it will be useful, +;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;;; GNU General Public License for more details. +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. ;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this software; see the file COPYING. If not, write to -;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;;; Boston, MA 02110-1301 USA +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (define-module (test-suite test-numbers) #:use-module (test-suite lib) diff --git a/test-suite/tests/srfi-98.test b/test-suite/tests/srfi-98.test new file mode 100644 index 000000000..ac0d5178e --- /dev/null +++ b/test-suite/tests/srfi-98.test @@ -0,0 +1,37 @@ +;;;; srfi-98.test --- Test suite for Guile's SRFI-98 functions. -*- scheme -*- +;;;; +;;;; Copyright 2009 Free Software Foundation, Inc. +;;;; +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +(define-module (test-srfi-98) + #:use-module (srfi srfi-98) + #:use-module (test-suite lib)) + +(with-test-prefix "get-environment-variable" + (pass-if "get-environment-variable retrieves binding" + (putenv "foo=bar") + (equal? (get-environment-variable "foo") "bar")) + + (pass-if "get-environment-variable #f on unbound name" + (unsetenv "foo") + (not (get-environment-variable "foo")))) + +(with-test-prefix "get-environment-variables" + + (pass-if "get-environment-variables contains binding" + (putenv "foo=bar") + (equal? (assoc-ref (get-environment-variables) "foo") "bar"))) + diff --git a/test-suite/tests/streams.test b/test-suite/tests/streams.test index 92277c19c..780021c7e 100644 --- a/test-suite/tests/streams.test +++ b/test-suite/tests/streams.test @@ -2,20 +2,19 @@ ;;;; ;;;; Copyright (C) 2004, 2006 Free Software Foundation, Inc. ;;;; -;;;; 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 2, or (at your option) -;;;; any later version. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. ;;;; -;;;; This program is distributed in the hope that it will be useful, +;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;;; GNU General Public License for more details. +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. ;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this software; see the file COPYING. If not, write to -;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;;; Boston, MA 02110-1301 USA +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (define-module (test-suite test-streams) :use-module (test-suite lib) diff --git a/test-suite/tests/strings.test b/test-suite/tests/strings.test index 51f163254..a35dd20d8 100644 --- a/test-suite/tests/strings.test +++ b/test-suite/tests/strings.test @@ -1,34 +1,238 @@ ;;;; strings.test --- test suite for Guile's string functions -*- scheme -*- ;;;; Jim Blandy --- August 1999 ;;;; -;;;; Copyright (C) 1999, 2001, 2004, 2005, 2006, 2008 Free Software Foundation, Inc. +;;;; Copyright (C) 1999, 2001, 2004, 2005, 2006, 2008, 2009 Free Software Foundation, Inc. ;;;; -;;;; 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 2, or (at your option) -;;;; any later version. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. ;;;; -;;;; This program is distributed in the hope that it will be useful, +;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;;; GNU General Public License for more details. +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. ;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this software; see the file COPYING. If not, write to -;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;;; Boston, MA 02110-1301 USA +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (define-module (test-strings) #:use-module (test-suite lib)) - (define exception:read-only-string (cons 'misc-error "^string is read-only")) +(define exception:illegal-escape + (cons 'read-error "illegal character in escape sequence")) ;; Create a string from integer char values, eg. (string-ints 65) => "A" (define (string-ints . args) (apply string (map integer->char args))) +;; +;; string internals +;; + +;; Some abbreviations +;; BMP - Basic Multilingual Plane (codepoints below U+FFFF) +;; SMP - Suplementary Multilingual Plane (codebpoints from U+10000 to U+1FFFF) + +(with-test-prefix "string internals" + + (pass-if "new string starts at 1st char in stringbuf" + (let ((s "abc")) + (= 0 (assq-ref (%string-dump s) 'start)))) + + (pass-if "length of new string same as stringbuf" + (let ((s "def")) + (= (string-length s) (assq-ref (%string-dump s) 'stringbuf-length)))) + + (pass-if "contents of new string same as stringbuf" + (let ((s "ghi")) + (string=? s (assq-ref (%string-dump s) 'stringbuf-chars)))) + + (pass-if "writable strings are not read-only" + (let ((s "zyx")) + (not (assq-ref (%string-dump s) 'read-only)))) + + (pass-if "read-only strings are read-only" + (let ((s (substring/read-only "zyx" 0))) + (assq-ref (%string-dump s) 'read-only))) + + (pass-if "null strings are inlined" + (let ((s "")) + (assq-ref (%string-dump s) 'stringbuf-inline))) + + (pass-if "short Latin-1 encoded strings are inlined" + (let ((s "m")) + (assq-ref (%string-dump s) 'stringbuf-inline))) + + (pass-if "long Latin-1 encoded strings are not inlined" + (let ((s "0123456789012345678901234567890123456789")) + (not (assq-ref (%string-dump s) 'stringbuf-inline)))) + + (pass-if "short UCS-4 encoded strings are not inlined" + (let ((s "\u0100")) + (not (assq-ref (%string-dump s) 'stringbuf-inline)))) + + (pass-if "long UCS-4 encoded strings are not inlined" + (let ((s "\u010012345678901234567890123456789")) + (not (assq-ref (%string-dump s) 'stringbuf-inline)))) + + (pass-if "new Latin-1 encoded strings are not shared" + (let ((s "abc")) + (not (assq-ref (%string-dump s) 'stringbuf-shared)))) + + (pass-if "new UCS-4 encoded strings are not shared" + (let ((s "\u0100bc")) + (not (assq-ref (%string-dump s) 'stringbuf-shared)))) + + ;; Should this be true? It isn't currently true. + (pass-if "null shared substrings are shared" + (let* ((s1 "") + (s2 (substring/shared s1 0 0))) + (throw 'untested) + (eq? (assq-ref (%string-dump s2) 'shared) + s1))) + + (pass-if "ASCII shared substrings are shared" + (let* ((s1 "foobar") + (s2 (substring/shared s1 0 3))) + (eq? (assq-ref (%string-dump s2) 'shared) + s1))) + + (pass-if "BMP shared substrings are shared" + (let* ((s1 "\u0100\u0101\u0102\u0103\u0104\u0105") + (s2 (substring/shared s1 0 3))) + (eq? (assq-ref (%string-dump s2) 'shared) + s1))) + + (pass-if "null substrings are not shared" + (let* ((s1 "") + (s2 (substring s1 0 0))) + (not (eq? (assq-ref (%string-dump s2) 'shared) + s1)))) + + (pass-if "ASCII substrings are not shared" + (let* ((s1 "foobar") + (s2 (substring s1 0 3))) + (not (eq? (assq-ref (%string-dump s2) 'shared) + s1)))) + + (pass-if "BMP substrings are not shared" + (let* ((s1 "\u0100\u0101\u0102\u0103\u0104\u0105") + (s2 (substring s1 0 3))) + (not (eq? (assq-ref (%string-dump s2) 'shared) + s1)))) + + (pass-if "ASCII substrings share stringbufs before copy-on-write" + (let* ((s1 "foobar") + (s2 (substring s1 0 3))) + (assq-ref (%string-dump s1) 'stringbuf-shared))) + + (pass-if "BMP substrings share stringbufs before copy-on-write" + (let* ((s1 "\u0100\u0101\u0102\u0103\u0104\u0105") + (s2 (substring s1 0 3))) + (assq-ref (%string-dump s1) 'stringbuf-shared))) + + (pass-if "ASCII substrings don't share stringbufs after copy-on-write" + (let* ((s1 "foobar") + (s2 (substring s1 0 3))) + (string-set! s2 0 #\F) + (not (assq-ref (%string-dump s2) 'stringbuf-shared)))) + + (pass-if "BMP substrings don't share stringbufs after copy-on-write" + (let* ((s1 "\u0100\u0101\u0102\u0103\u0104\u0105") + (s2 (substring s1 0 3))) + (string-set! s2 0 #\F) + (not (assq-ref (%string-dump s2) 'stringbuf-shared)))) + + (with-test-prefix "encodings" + + (pass-if "null strings are Latin-1 encoded" + (let ((s "")) + (not (assq-ref (%string-dump s) 'stringbuf-wide)))) + + (pass-if "ASCII strings are Latin-1 encoded" + (let ((s "jkl")) + (not (assq-ref (%string-dump s) 'stringbuf-wide)))) + + (pass-if "Latin-1 strings are Latin-1 encoded" + (let ((s "\xC0\xC1\xC2")) + (not (assq-ref (%string-dump s) 'stringbuf-wide)))) + + (pass-if "BMP strings are UCS-4 encoded" + (let ((s "\u0100\u0101\x0102")) + (assq-ref (%string-dump s) 'stringbuf-wide))) + + (pass-if "SMP strings are UCS-4 encoded" + (let ((s "\U010300\u010301\x010302")) + (assq-ref (%string-dump s) 'stringbuf-wide))) + + (pass-if "null list->string is Latin-1 encoded" + (let ((s (string-ints))) + (not (assq-ref (%string-dump s) 'stringbuf-wide)))) + + (pass-if "ASCII list->string is Latin-1 encoded" + (let ((s (string-ints 65 66 67))) + (not (assq-ref (%string-dump s) 'stringbuf-wide)))) + + (pass-if "Latin-1 list->string is Latin-1 encoded" + (let ((s (string-ints #xc0 #xc1 #xc2))) + (not (assq-ref (%string-dump s) 'stringbuf-wide)))) + + (pass-if "BMP list->string is UCS-4 encoded" + (let ((s (string-ints #x0100 #x0101 #x0102))) + (assq-ref (%string-dump s) 'stringbuf-wide))) + + (pass-if "SMP list->string is UCS-4 encoded" + (let ((s (string-ints #x010300 #x010301 #x010302))) + (assq-ref (%string-dump s) 'stringbuf-wide))) + + (pass-if "encoding of string not based on escape style" + (let ((s "\U000040")) + (not (assq-ref (%string-dump s) 'stringbuf-wide)))))) + +(with-test-prefix "hex escapes" + + (pass-if-exception "non-hex char in two-digit hex-escape" + exception:illegal-escape + (with-input-from-string "\"\\x0g\"" read)) + + (pass-if-exception "non-hex char in four-digit hex-escape" + exception:illegal-escape + (with-input-from-string "\"\\u000g\"" read)) + + (pass-if-exception "non-hex char in six-digit hex-escape" + exception:illegal-escape + (with-input-from-string "\"\\U00000g\"" read)) + + (pass-if-exception "premature termination of two-digit hex-escape" + exception:illegal-escape + (with-input-from-string "\"\\x0\"" read)) + + (pass-if-exception "premature termination of four-digit hex-escape" + exception:illegal-escape + (with-input-from-string "\"\\u000\"" read)) + + (pass-if-exception "premature termination of six-digit hex-escape" + exception:illegal-escape + (with-input-from-string "\"\\U00000\"" read)) + + (pass-if "extra hex digits ignored for two-digit hex escape" + (eqv? (string-ref "--\xfff--" 2) + (integer->char #xff))) + + (pass-if "extra hex digits ignored for four-digit hex escape" + (eqv? (string-ref "--\u0100f--" 2) + (integer->char #x0100))) + + (pass-if "extra hex digits ignored for six-digit hex escape" + (eqv? (string-ref "--\U010300f--" 2) + (integer->char #x010300))) + + (pass-if "escaped characters match non-escaped ASCII characters" + (string=? "ABC" "\x41\u0042\U000043"))) ;; ;; string=? @@ -182,8 +386,20 @@ exception:out-of-range (string-ref "hello" -1)) - (pass-if "regular string" - (char=? (string-ref "GNU Guile" 4) #\G))) + (pass-if "regular string, ASCII char" + (char=? (string-ref "GNU Guile" 4) #\G)) + + (pass-if "regular string, hex escaped Latin-1 char" + (char=? (string-ref "--\xff--" 2) + (integer->char #xff))) + + (pass-if "regular string, hex escaped BMP char" + (char=? (string-ref "--\u0100--" 2) + (integer->char #x0100))) + + (pass-if "regular string, hex escaped SMP char" + (char=? (string-ref "--\U010300--" 2) + (integer->char #x010300)))) ;; ;; string-set! @@ -211,12 +427,37 @@ exception:read-only-string (string-set! (substring/read-only "abc" 0) 1 #\space)) - (pass-if "regular string" + (pass-if "regular string, ASCII char" (let ((s (string-copy "GNU guile"))) (string-set! s 4 #\G) - (char=? (string-ref s 4) #\G)))) + (char=? (string-ref s 4) #\G))) + (pass-if "regular string, Latin-1 char" + (let ((s (string-copy "GNU guile"))) + (string-set! s 4 (integer->char #xfe)) + (char=? (string-ref s 4) (integer->char #xfe)))) + (pass-if "regular string, BMP char" + (let ((s (string-copy "GNU guile"))) + (string-set! s 4 (integer->char #x0100)) + (char=? (string-ref s 4) (integer->char #x0100)))) + + (pass-if "regular string, SMP char" + (let ((s (string-copy "GNU guile"))) + (string-set! s 4 (integer->char #x010300)) + (char=? (string-ref s 4) (integer->char #x010300))))) + +;; +;; list->string +;; +(with-test-prefix "string" + + (pass-if-exception "convert circular list to string" + exception:wrong-type-arg + (let ((foo (list #\a #\b #\c))) + (set-cdr! (cddr foo) (cdr foo)) + (apply string foo)))) + (with-test-prefix "string-split" ;; in guile 1.6.7 and earlier, character >=128 wasn't matched in the string diff --git a/test-suite/tests/structs.test b/test-suite/tests/structs.test index 127115eb2..e114abb1a 100644 --- a/test-suite/tests/structs.test +++ b/test-suite/tests/structs.test @@ -3,20 +3,19 @@ ;;;; ;;;; Copyright (C) 2006, 2007 Free Software Foundation, Inc. ;;;; -;;;; 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 2, or (at your option) -;;;; any later version. -;;;; -;;;; This program is distributed in the hope that it will be useful, +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;;; GNU General Public License for more details. -;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this software; see the file COPYING. If not, write to -;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;;; Boston, MA 02110-1301 USA +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (define-module (test-suite test-structs) :use-module (test-suite lib)) diff --git a/test-suite/tests/symbols.test b/test-suite/tests/symbols.test index 3fe3402f8..3b1abe1e9 100644 --- a/test-suite/tests/symbols.test +++ b/test-suite/tests/symbols.test @@ -1,21 +1,20 @@ ;;;; symbols.test --- test suite for Guile's symbols -*- scheme -*- ;;;; -;;;; Copyright (C) 2001, 2006, 2008 Free Software Foundation, Inc. +;;;; Copyright (C) 2001, 2006, 2008, 2009 Free Software Foundation, Inc. ;;;; -;;;; 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 2, or (at your option) -;;;; any later version. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. ;;;; -;;;; This program is distributed in the hope that it will be useful, +;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;;; GNU General Public License for more details. +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. ;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this software; see the file COPYING. If not, write to -;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;;; Boston, MA 02110-1301 USA +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (define-module (test-suite test-symbols) #:use-module (test-suite lib) @@ -32,6 +31,84 @@ (define (documented? object) (not (not (object-documentation object)))) +(define (symbol-length s) + (string-length (symbol->string s))) + +;; +;; symbol internals +;; + +(with-test-prefix "symbol internals" + + (pass-if "length of new symbol same as stringbuf" + (let ((s 'def)) + (= (symbol-length s) (assq-ref (%symbol-dump s) 'stringbuf-length)))) + + (pass-if "contents of new symbol same as stringbuf" + (let ((s 'ghi)) + (string=? (symbol->string s) + (assq-ref (%symbol-dump s) 'stringbuf-chars)))) + + (pass-if "the null symbol is inlined" + (let ((s '#{}#)) + (assq-ref (%symbol-dump s) 'stringbuf-inline))) + + (pass-if "short Latin-1-encoded symbols are inlined" + (let ((s 'm)) + (assq-ref (%symbol-dump s) 'stringbuf-inline))) + + (pass-if "long Latin-1-encoded symbols are not inlined" + (let ((s 'x0123456789012345678901234567890123456789)) + (not (assq-ref (%symbol-dump s) 'stringbuf-inline)))) + + ;; symbol->string isn't ready for UCS-4 yet + + ;;(pass-if "short UCS-4-encoded symbols are not inlined" + ;; (let ((s (string->symbol "\u0100"))) + ;; (not (assq-ref (%symbol-dump s) 'stringbuf-inline)))) + + ;;(pass-if "long UCS-4-encoded symbols are not inlined" + ;; (let ((s (string->symbol "\u010012345678901234567890123456789"))) + ;; (not (assq-ref (%symbol-dump s) 'stringbuf-inline)))) + + (with-test-prefix "hashes" + + (pass-if "equal symbols have equal hashes" + (let ((s1 'mux) + (s2 'mux)) + (= (assq-ref (%symbol-dump s1) 'hash) + (assq-ref (%symbol-dump s2) 'hash)))) + + (pass-if "different symbols have different hashes" + (let ((s1 'mux) + (s2 'muy)) + (not (= (assq-ref (%symbol-dump s1) 'hash) + (assq-ref (%symbol-dump s2) 'hash)))))) + + (with-test-prefix "encodings" + + (pass-if "the null symbol is Latin-1 encoded" + (let ((s '#{}#)) + (not (assq-ref (%symbol-dump s) 'stringbuf-wide)))) + + (pass-if "ASCII symbols are Latin-1 encoded" + (let ((s 'jkl)) + (not (assq-ref (%symbol-dump s) 'stringbuf-wide)))) + + (pass-if "Latin-1 symbols are Latin-1 encoded" + (let ((s (string->symbol "\xC0\xC1\xC2"))) + (not (assq-ref (%symbol-dump s) 'stringbuf-wide)))) + + ;; symbol->string isn't ready for UCS-4 yet + + ;;(pass-if "BMP symbols are UCS-4 encoded" + ;; (let ((s (string->symbol "\u0100\u0101\x0102"))) + ;; (assq-ref (%symbol-dump s) 'stringbuf-wide))) + + ;;(pass-if "SMP symbols are UCS-4 encoded" + ;; (let ((s (string->symbol "\U010300\u010301\x010302"))) + ;; (assq-ref (%symbol-dump s) 'stringbuf-wide))) + )) ;;; ;;; symbol? diff --git a/test-suite/tests/syncase.test b/test-suite/tests/syncase.test index c681fc381..4cd93369a 100644 --- a/test-suite/tests/syncase.test +++ b/test-suite/tests/syncase.test @@ -2,20 +2,19 @@ ;;;; ;;;; Copyright (C) 2001, 2006 Free Software Foundation, Inc. ;;;; -;;;; 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 2, or (at your option) -;;;; any later version. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. ;;;; -;;;; This program is distributed in the hope that it will be useful, +;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;;; GNU General Public License for more details. +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. ;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this software; see the file COPYING. If not, write to -;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;;; Boston, MA 02110-1301 USA +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;; These tests are in a module so that the syntax transformer does not ;; affect code outside of this file. diff --git a/test-suite/tests/syntax.test b/test-suite/tests/syntax.test index 1277e5204..0593ea6a6 100644 --- a/test-suite/tests/syntax.test +++ b/test-suite/tests/syntax.test @@ -2,25 +2,29 @@ ;;;; ;;;; Copyright (C) 2001,2003,2004, 2005, 2006 Free Software Foundation, Inc. ;;;; -;;;; 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 2, or (at your option) -;;;; any later version. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. ;;;; -;;;; This program is distributed in the hope that it will be useful, +;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;;; GNU General Public License for more details. +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. ;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this software; see the file COPYING. If not, write to -;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;;; Boston, MA 02110-1301 USA +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (define-module (test-suite test-syntax) :use-module (test-suite lib)) +(define exception:generic-syncase-error + (cons 'syntax-error "source expression failed to match")) +(define exception:unexpected-syntax + (cons 'syntax-error "unexpected syntax")) + (define exception:bad-expression (cons 'syntax-error "Bad expression")) @@ -29,22 +33,32 @@ (define exception:missing-expr (cons 'syntax-error "Missing expression")) (define exception:missing-body-expr - (cons 'syntax-error "Missing body expression")) + (cons 'syntax-error "no expressions in body")) (define exception:extra-expr (cons 'syntax-error "Extra expression")) (define exception:illegal-empty-combination (cons 'syntax-error "Illegal empty combination")) +(define exception:bad-lambda + '(syntax-error . "bad lambda")) +(define exception:bad-let + '(syntax-error . "bad let ")) +(define exception:bad-letrec + '(syntax-error . "bad letrec ")) +(define exception:bad-set! + '(syntax-error . "bad set!")) +(define exception:bad-quote + '(syntax-error . "quote: bad syntax")) (define exception:bad-bindings (cons 'syntax-error "Bad bindings")) (define exception:bad-binding (cons 'syntax-error "Bad binding")) (define exception:duplicate-binding - (cons 'syntax-error "Duplicate binding")) + (cons 'syntax-error "duplicate bound variable")) (define exception:bad-body (cons 'misc-error "^bad body")) (define exception:bad-formals - (cons 'syntax-error "Bad formals")) + '(syntax-error . "invalid parameter list")) (define exception:bad-formal (cons 'syntax-error "Bad formal")) (define exception:duplicate-formal @@ -67,13 +81,13 @@ (with-test-prefix "Bad argument list" (pass-if-exception "improper argument list of length 1" - exception:wrong-num-args + exception:generic-syncase-error (eval '(let ((foo (lambda (x y) #t))) (foo . 1)) (interaction-environment))) (pass-if-exception "improper argument list of length 2" - exception:wrong-num-args + exception:generic-syncase-error (eval '(let ((foo (lambda (x y) #t))) (foo 1 . 2)) (interaction-environment)))) @@ -88,7 +102,7 @@ ;; Fixed on 2001-3-3 (pass-if-exception "empty parentheses \"()\"" - exception:illegal-empty-combination + exception:unexpected-syntax (eval '() (interaction-environment))))) @@ -106,28 +120,32 @@ (with-test-prefix "unquote-splicing" (pass-if-exception "extra arguments" - exception:missing/extra-expr - (quasiquote ((unquote-splicing (list 1 2) (list 3 4))))))) + '(syntax-error . "unquote-splicing takes exactly one argument") + (eval '(quasiquote ((unquote-splicing (list 1 2) (list 3 4)))) + (interaction-environment))))) (with-test-prefix "begin" (pass-if "legal (begin)" - (begin) - #t) + (eval '(begin (begin) #t) (interaction-environment))) (with-test-prefix "unmemoization" + ;; FIXME. I have no idea why, but the expander is filling in (if #f + ;; #f) as the second arm of the if, if the second arm is missing. I + ;; thought I made it not do that. But in the meantime, let's adapt, + ;; since that's not what we're testing. + (pass-if "normal begin" - (let ((foo (lambda () (if (= 1 1) (begin (+ 1) (+ 2)))))) - (foo) ; make sure, memoization has been performed + (let ((foo (lambda () (if (= 1 1) (begin (+ 1) (+ 2)) #f)))) (equal? (procedure-source foo) - '(lambda () (if (= 1 1) (begin (+ 1) (+ 2))))))) + '(lambda () (if (= 1 1) (begin (+ 1) (+ 2)) #f))))) (pass-if "redundant nested begin" - (let ((foo (lambda () (if (= 1 1) (begin (+ 1) (begin (+ 2) (+ 3))))))) + (let ((foo (lambda () (if (= 1 1) (begin (+ 1) (begin (+ 2) (+ 3))) #f)))) (foo) ; make sure, memoization has been performed (equal? (procedure-source foo) - '(lambda () (if (= 1 1) (begin (+ 1) (begin (+ 2) (+ 3)))))))) + '(lambda () (if (= 1 1) (begin (+ 1) (begin (+ 2) (+ 3))) #f))))) (pass-if "redundant begin at start of body" (let ((foo (lambda () (begin (+ 1) (+ 2))))) ; should be optimized @@ -135,10 +153,20 @@ (equal? (procedure-source foo) '(lambda () (begin (+ 1) (+ 2))))))) - (expect-fail-exception "illegal (begin)" - exception:bad-body - (if #t (begin)) - #t)) + (pass-if-exception "illegal (begin)" + exception:generic-syncase-error + (eval '(begin (if #t (begin)) #t) (interaction-environment)))) + +(define-syntax matches? + (syntax-rules (_) + ((_ (op arg ...) pat) (let ((x (op arg ...))) + (matches? x pat))) + ((_ x ()) (null? x)) + ((_ x (a . b)) (and (pair? x) + (matches? (car x) a) + (matches? (cdr x) b))) + ((_ x _) #t) + ((_ x pat) (equal? x 'pat)))) (with-test-prefix "lambda" @@ -146,30 +174,28 @@ (pass-if "normal lambda" (let ((foo (lambda () (lambda (x y) (+ x y))))) - ((foo) 1 2) ; make sure, memoization has been performed - (equal? (procedure-source foo) - '(lambda () (lambda (x y) (+ x y)))))) + (matches? (procedure-source foo) + (lambda () (lambda (_ _) (+ _ _)))))) (pass-if "lambda with documentation" (let ((foo (lambda () (lambda (x y) "docstring" (+ x y))))) - ((foo) 1 2) ; make sure, memoization has been performed - (equal? (procedure-source foo) - '(lambda () (lambda (x y) "docstring" (+ x y))))))) + (matches? (procedure-source foo) + (lambda () (lambda (_ _) "docstring" (+ _ _))))))) (with-test-prefix "bad formals" (pass-if-exception "(lambda)" - exception:missing-expr + exception:bad-lambda (eval '(lambda) (interaction-environment))) (pass-if-exception "(lambda . \"foo\")" - exception:bad-expression + exception:bad-lambda (eval '(lambda . "foo") (interaction-environment))) (pass-if-exception "(lambda \"foo\")" - exception:missing-expr + exception:bad-lambda (eval '(lambda "foo") (interaction-environment))) @@ -179,22 +205,22 @@ (interaction-environment))) (pass-if-exception "(lambda (x 1) 2)" - exception:bad-formal + exception:bad-formals (eval '(lambda (x 1) 2) (interaction-environment))) (pass-if-exception "(lambda (1 x) 2)" - exception:bad-formal + exception:bad-formals (eval '(lambda (1 x) 2) (interaction-environment))) (pass-if-exception "(lambda (x \"a\") 2)" - exception:bad-formal + exception:bad-formals (eval '(lambda (x "a") 2) (interaction-environment))) (pass-if-exception "(lambda (\"a\" x) 2)" - exception:bad-formal + exception:bad-formals (eval '(lambda ("a" x) 2) (interaction-environment)))) @@ -202,20 +228,20 @@ ;; Fixed on 2001-3-3 (pass-if-exception "(lambda (x x) 1)" - exception:duplicate-formal + exception:bad-formals (eval '(lambda (x x) 1) (interaction-environment))) ;; Fixed on 2001-3-3 (pass-if-exception "(lambda (x x x) 1)" - exception:duplicate-formal + exception:bad-formals (eval '(lambda (x x x) 1) (interaction-environment)))) (with-test-prefix "bad body" (pass-if-exception "(lambda ())" - exception:missing-expr + exception:bad-lambda (eval '(lambda ()) (interaction-environment))))) @@ -225,9 +251,8 @@ (pass-if "normal let" (let ((foo (lambda () (let ((i 1) (j 2)) (+ i j))))) - (foo) ; make sure, memoization has been performed - (equal? (procedure-source foo) - '(lambda () (let ((i 1) (j 2)) (+ i j))))))) + (matches? (procedure-source foo) + (lambda () (let ((_ 1) (_ 2)) (+ _ _))))))) (with-test-prefix "bindings" @@ -238,42 +263,42 @@ (with-test-prefix "bad bindings" (pass-if-exception "(let)" - exception:missing-expr + exception:bad-let (eval '(let) (interaction-environment))) (pass-if-exception "(let 1)" - exception:missing-expr + exception:bad-let (eval '(let 1) (interaction-environment))) (pass-if-exception "(let (x))" - exception:missing-expr + exception:bad-let (eval '(let (x)) (interaction-environment))) (pass-if-exception "(let ((x)))" - exception:missing-expr + exception:bad-let (eval '(let ((x))) (interaction-environment))) (pass-if-exception "(let (x) 1)" - exception:bad-binding + exception:bad-let (eval '(let (x) 1) (interaction-environment))) (pass-if-exception "(let ((x)) 3)" - exception:bad-binding + exception:bad-let (eval '(let ((x)) 3) (interaction-environment))) (pass-if-exception "(let ((x 1) y) x)" - exception:bad-binding + exception:bad-let (eval '(let ((x 1) y) x) (interaction-environment))) (pass-if-exception "(let ((1 2)) 3)" - exception:bad-variable + exception:bad-let (eval '(let ((1 2)) 3) (interaction-environment)))) @@ -287,12 +312,12 @@ (with-test-prefix "bad body" (pass-if-exception "(let ())" - exception:missing-expr + exception:bad-let (eval '(let ()) (interaction-environment))) (pass-if-exception "(let ((x 1)))" - exception:missing-expr + exception:bad-let (eval '(let ((x 1))) (interaction-environment))))) @@ -307,19 +332,19 @@ (with-test-prefix "bad bindings" (pass-if-exception "(let x (y))" - exception:missing-expr + exception:bad-let (eval '(let x (y)) (interaction-environment)))) (with-test-prefix "bad body" (pass-if-exception "(let x ())" - exception:missing-expr + exception:bad-let (eval '(let x ()) (interaction-environment))) (pass-if-exception "(let x ((y 1)))" - exception:missing-expr + exception:bad-let (eval '(let x ((y 1))) (interaction-environment))))) @@ -329,19 +354,16 @@ (pass-if "normal let*" (let ((foo (lambda () (let* ((x 1) (y 2)) (+ x y))))) - (foo) ; make sure, memoization has been performed - (equal? (procedure-source foo) - '(lambda () (let* ((x 1) (y 2)) (+ x y)))))) + (matches? (procedure-source foo) + (lambda () (let ((_ 1)) (let ((_ 2)) (+ _ _))))))) (pass-if "let* without bindings" (let ((foo (lambda () (let ((x 1) (y 2)) (let* () (and (= x 1) (= y 2))))))) - (foo) ; make sure, memoization has been performed - (equal? (procedure-source foo) - '(lambda () (let ((x 1) (y 2)) - (let* () - (and (= x 1) (= y 2))))))))) + (matches? (procedure-source foo) + (lambda () (let ((_ 1) (_ 2)) + (if (= _ 1) (= _ 2) #f))))))) (with-test-prefix "bindings" @@ -361,59 +383,59 @@ (with-test-prefix "bad bindings" (pass-if-exception "(let*)" - exception:missing-expr + exception:generic-syncase-error (eval '(let*) (interaction-environment))) (pass-if-exception "(let* 1)" - exception:missing-expr + exception:generic-syncase-error (eval '(let* 1) (interaction-environment))) (pass-if-exception "(let* (x))" - exception:missing-expr + exception:generic-syncase-error (eval '(let* (x)) (interaction-environment))) (pass-if-exception "(let* (x) 1)" - exception:bad-binding + exception:generic-syncase-error (eval '(let* (x) 1) (interaction-environment))) (pass-if-exception "(let* ((x)) 3)" - exception:bad-binding + exception:generic-syncase-error (eval '(let* ((x)) 3) (interaction-environment))) (pass-if-exception "(let* ((x 1) y) x)" - exception:bad-binding + exception:generic-syncase-error (eval '(let* ((x 1) y) x) (interaction-environment))) (pass-if-exception "(let* x ())" - exception:bad-bindings + exception:generic-syncase-error (eval '(let* x ()) (interaction-environment))) (pass-if-exception "(let* x (y))" - exception:bad-bindings + exception:generic-syncase-error (eval '(let* x (y)) (interaction-environment))) (pass-if-exception "(let* ((1 2)) 3)" - exception:bad-variable + exception:generic-syncase-error (eval '(let* ((1 2)) 3) (interaction-environment)))) (with-test-prefix "bad body" (pass-if-exception "(let* ())" - exception:missing-expr + exception:generic-syncase-error (eval '(let* ()) (interaction-environment))) (pass-if-exception "(let* ((x 1)))" - exception:missing-expr + exception:generic-syncase-error (eval '(let* ((x 1))) (interaction-environment))))) @@ -423,9 +445,8 @@ (pass-if "normal letrec" (let ((foo (lambda () (letrec ((i 1) (j 2)) (+ i j))))) - (foo) ; make sure, memoization has been performed - (equal? (procedure-source foo) - '(lambda () (letrec ((i 1) (j 2)) (+ i j))))))) + (matches? (procedure-source foo) + (lambda () (letrec ((_ 1) (_ 2)) (+ _ _))))))) (with-test-prefix "bindings" @@ -437,47 +458,47 @@ (with-test-prefix "bad bindings" (pass-if-exception "(letrec)" - exception:missing-expr + exception:bad-letrec (eval '(letrec) (interaction-environment))) (pass-if-exception "(letrec 1)" - exception:missing-expr + exception:bad-letrec (eval '(letrec 1) (interaction-environment))) (pass-if-exception "(letrec (x))" - exception:missing-expr + exception:bad-letrec (eval '(letrec (x)) (interaction-environment))) (pass-if-exception "(letrec (x) 1)" - exception:bad-binding + exception:bad-letrec (eval '(letrec (x) 1) (interaction-environment))) (pass-if-exception "(letrec ((x)) 3)" - exception:bad-binding + exception:bad-letrec (eval '(letrec ((x)) 3) (interaction-environment))) (pass-if-exception "(letrec ((x 1) y) x)" - exception:bad-binding + exception:bad-letrec (eval '(letrec ((x 1) y) x) (interaction-environment))) (pass-if-exception "(letrec x ())" - exception:bad-bindings + exception:bad-letrec (eval '(letrec x ()) (interaction-environment))) (pass-if-exception "(letrec x (y))" - exception:bad-bindings + exception:bad-letrec (eval '(letrec x (y)) (interaction-environment))) (pass-if-exception "(letrec ((1 2)) 3)" - exception:bad-variable + exception:bad-letrec (eval '(letrec ((1 2)) 3) (interaction-environment)))) @@ -491,12 +512,12 @@ (with-test-prefix "bad body" (pass-if-exception "(letrec ())" - exception:missing-expr + exception:bad-letrec (eval '(letrec ()) (interaction-environment))) (pass-if-exception "(letrec ((x 1)))" - exception:missing-expr + exception:bad-letrec (eval '(letrec ((x 1))) (interaction-environment))))) @@ -508,17 +529,17 @@ (let ((foo (lambda (x) (if x (+ 1) (+ 2))))) (foo #t) ; make sure, memoization has been performed (foo #f) ; make sure, memoization has been performed - (equal? (procedure-source foo) - '(lambda (x) (if x (+ 1) (+ 2)))))) + (matches? (procedure-source foo) + (lambda (_) (if _ (+ 1) (+ 2)))))) - (pass-if "if without else" + (expect-fail "if without else" (let ((foo (lambda (x) (if x (+ 1))))) (foo #t) ; make sure, memoization has been performed (foo #f) ; make sure, memoization has been performed (equal? (procedure-source foo) '(lambda (x) (if x (+ 1)))))) - (pass-if "if #f without else" + (expect-fail "if #f without else" (let ((foo (lambda () (if #f #f)))) (foo) ; make sure, memoization has been performed (equal? (procedure-source foo) @@ -527,12 +548,12 @@ (with-test-prefix "missing or extra expressions" (pass-if-exception "(if)" - exception:missing/extra-expr + exception:generic-syncase-error (eval '(if) (interaction-environment))) (pass-if-exception "(if 1 2 3 4)" - exception:missing/extra-expr + exception:generic-syncase-error (eval '(if 1 2 3 4) (interaction-environment))))) @@ -594,78 +615,77 @@ (eq? 'ok (cond (#t identity =>) (else #f))))) (pass-if-exception "missing recipient" - '(syntax-error . "Missing recipient") + '(syntax-error . "cond: wrong number of receiver expressions") (cond (#t identity =>))) (pass-if-exception "extra recipient" - '(syntax-error . "Extra expression") + '(syntax-error . "cond: wrong number of receiver expressions") (cond (#t identity => identity identity)))) (with-test-prefix "unmemoization" + ;; FIXME: the (if #f #f) is a hack! (pass-if "normal clauses" - (let ((foo (lambda (x) (cond ((= x 1) 'bar) ((= x 2) 'baz))))) - (foo 1) ; make sure, memoization has been performed - (foo 2) ; make sure, memoization has been performed + (let ((foo (lambda () (cond ((= x 1) 'bar) ((= x 2) 'baz))))) (equal? (procedure-source foo) - '(lambda (x) (cond ((= x 1) 'bar) ((= x 2) 'baz)))))) + '(lambda () (if (= x 1) 'bar (if (= x 2) 'baz (if #f #f))))))) (pass-if "else" (let ((foo (lambda () (cond (else 'bar))))) - (foo) ; make sure, memoization has been performed (equal? (procedure-source foo) - '(lambda () (cond (else 'bar)))))) + '(lambda () 'bar)))) + ;; FIXME: the (if #f #f) is a hack! (pass-if "=>" (let ((foo (lambda () (cond (#t => identity))))) - (foo) ; make sure, memoization has been performed - (equal? (procedure-source foo) - '(lambda () (cond (#t => identity))))))) + (matches? (procedure-source foo) + (lambda () (let ((_ #t)) + (if _ (identity _) (if #f #f)))))))) (with-test-prefix "bad or missing clauses" (pass-if-exception "(cond)" - exception:missing-clauses + exception:generic-syncase-error (eval '(cond) (interaction-environment))) (pass-if-exception "(cond #t)" - exception:bad-cond-clause + exception:generic-syncase-error (eval '(cond #t) (interaction-environment))) (pass-if-exception "(cond 1)" - exception:bad-cond-clause + exception:generic-syncase-error (eval '(cond 1) (interaction-environment))) (pass-if-exception "(cond 1 2)" - exception:bad-cond-clause + exception:generic-syncase-error (eval '(cond 1 2) (interaction-environment))) (pass-if-exception "(cond 1 2 3)" - exception:bad-cond-clause + exception:generic-syncase-error (eval '(cond 1 2 3) (interaction-environment))) (pass-if-exception "(cond 1 2 3 4)" - exception:bad-cond-clause + exception:generic-syncase-error (eval '(cond 1 2 3 4) (interaction-environment))) (pass-if-exception "(cond ())" - exception:bad-cond-clause + exception:generic-syncase-error (eval '(cond ()) (interaction-environment))) (pass-if-exception "(cond () 1)" - exception:bad-cond-clause + exception:generic-syncase-error (eval '(cond () 1) (interaction-environment))) (pass-if-exception "(cond (1) 1)" - exception:bad-cond-clause + exception:generic-syncase-error (eval '(cond (1) 1) (interaction-environment)))) @@ -683,7 +703,7 @@ (with-test-prefix "case is hygienic" (pass-if-exception "bound 'else is handled correctly" - exception:bad-case-labels + exception:generic-syncase-error (eval '(let ((else #f)) (case 1 (else #f))) (interaction-environment)))) @@ -691,79 +711,83 @@ (pass-if "normal clauses" (let ((foo (lambda (x) (case x ((1) 'bar) ((2) 'baz) (else 'foobar))))) - (foo 1) ; make sure, memoization has been performed - (foo 2) ; make sure, memoization has been performed - (foo 3) ; make sure, memoization has been performed - (equal? (procedure-source foo) - '(lambda (x) (case x ((1) 'bar) ((2) 'baz) (else 'foobar)))))) + (matches? (procedure-source foo) + (lambda (_) + (if ((@@ (guile) memv) _ '(1)) + 'bar + (if ((@@ (guile) memv) _ '(2)) + 'baz + 'foobar)))))) (pass-if "empty labels" (let ((foo (lambda (x) (case x ((1) 'bar) (() 'baz) (else 'foobar))))) - (foo 1) ; make sure, memoization has been performed - (foo 2) ; make sure, memoization has been performed - (foo 3) ; make sure, memoization has been performed - (equal? (procedure-source foo) - '(lambda (x) (case x ((1) 'bar) (() 'baz) (else 'foobar))))))) + (matches? (procedure-source foo) + (lambda (_) + (if ((@@ (guile) memv) _ '(1)) + 'bar + (if ((@@ (guile) memv) _ '()) + 'baz + 'foobar))))))) (with-test-prefix "bad or missing clauses" (pass-if-exception "(case)" - exception:missing-clauses + exception:generic-syncase-error (eval '(case) (interaction-environment))) (pass-if-exception "(case . \"foo\")" - exception:bad-expression + exception:generic-syncase-error (eval '(case . "foo") (interaction-environment))) (pass-if-exception "(case 1)" - exception:missing-clauses + exception:generic-syncase-error (eval '(case 1) (interaction-environment))) (pass-if-exception "(case 1 . \"foo\")" - exception:bad-expression + exception:generic-syncase-error (eval '(case 1 . "foo") (interaction-environment))) (pass-if-exception "(case 1 \"foo\")" - exception:bad-case-clause + exception:generic-syncase-error (eval '(case 1 "foo") (interaction-environment))) (pass-if-exception "(case 1 ())" - exception:bad-case-clause + exception:generic-syncase-error (eval '(case 1 ()) (interaction-environment))) (pass-if-exception "(case 1 (\"foo\"))" - exception:bad-case-clause + exception:generic-syncase-error (eval '(case 1 ("foo")) (interaction-environment))) (pass-if-exception "(case 1 (\"foo\" \"bar\"))" - exception:bad-case-labels + exception:generic-syncase-error (eval '(case 1 ("foo" "bar")) (interaction-environment))) (pass-if-exception "(case 1 ((2) \"bar\") . \"foo\")" - exception:bad-expression + exception:generic-syncase-error (eval '(case 1 ((2) "bar") . "foo") (interaction-environment))) (pass-if-exception "(case 1 ((2) \"bar\") (else))" - exception:bad-case-clause + exception:generic-syncase-error (eval '(case 1 ((2) "bar") (else)) (interaction-environment))) (pass-if-exception "(case 1 (else #f) . \"foo\")" - exception:bad-expression + exception:generic-syncase-error (eval '(case 1 (else #f) . "foo") (interaction-environment))) (pass-if-exception "(case 1 (else #f) ((1) #t))" - exception:misplaced-else-clause + exception:generic-syncase-error (eval '(case 1 (else #f) ((1) #t)) (interaction-environment))))) @@ -780,14 +804,6 @@ (eval '(define round round) m) (eq? (module-ref m 'round) round))) - (with-test-prefix "currying" - - (pass-if "(define ((foo)) #f)" - (eval '(begin - (define ((foo)) #t) - ((foo))) - (interaction-environment)))) - (with-test-prefix "unmemoization" (pass-if "definition unmemoized without prior execution" @@ -809,7 +825,7 @@ (with-test-prefix "missing or extra expressions" (pass-if-exception "(define)" - exception:missing-expr + exception:generic-syncase-error (eval '(define) (interaction-environment))))) @@ -886,34 +902,10 @@ 'ok) (bar)) (foo) - (equal? + (matches? (procedure-source foo) - '(lambda () (letrec ((bar (lambda () (quote ok)))) (bar))))) - (interaction-environment)))) - -(with-test-prefix "do" - - (with-test-prefix "unmemoization" - - (pass-if "normal case" - (let ((foo (lambda () (do ((i 1 (+ i 1)) (j 2)) - ((> i 9) (+ i j)) - (identity i))))) - (foo) ; make sure, memoization has been performed - (equal? (procedure-source foo) - '(lambda () (do ((i 1 (+ i 1)) (j 2)) - ((> i 9) (+ i j)) - (identity i)))))) - - (pass-if "reduced case" - (let ((foo (lambda () (do ((i 1 (+ i 1)) (j 2 j)) ; redundant step for j - ((> i 9) (+ i j)) - (identity i))))) - (foo) ; make sure, memoization has been performed - (equal? (procedure-source foo) - '(lambda () (do ((i 1 (+ i 1)) (j 2)) ; no redundancy here - ((> i 9) (+ i j)) - (identity i)))))))) + (lambda () (letrec ((_ (lambda () (quote ok)))) (_))))) + (current-module)))) (with-test-prefix "set!" @@ -922,50 +914,50 @@ (pass-if "normal set!" (let ((foo (lambda (x) (set! x (+ 1 x))))) (foo 1) ; make sure, memoization has been performed - (equal? (procedure-source foo) - '(lambda (x) (set! x (+ 1 x))))))) + (matches? (procedure-source foo) + (lambda (_) (set! _ (+ 1 _))))))) (with-test-prefix "missing or extra expressions" (pass-if-exception "(set!)" - exception:missing/extra-expr + exception:bad-set! (eval '(set!) (interaction-environment))) (pass-if-exception "(set! 1)" - exception:missing/extra-expr + exception:bad-set! (eval '(set! 1) (interaction-environment))) (pass-if-exception "(set! 1 2 3)" - exception:missing/extra-expr + exception:bad-set! (eval '(set! 1 2 3) (interaction-environment)))) (with-test-prefix "bad variable" (pass-if-exception "(set! \"\" #t)" - exception:bad-variable + exception:bad-set! (eval '(set! "" #t) (interaction-environment))) (pass-if-exception "(set! 1 #t)" - exception:bad-variable + exception:bad-set! (eval '(set! 1 #t) (interaction-environment))) (pass-if-exception "(set! #t #f)" - exception:bad-variable + exception:bad-set! (eval '(set! #t #f) (interaction-environment))) (pass-if-exception "(set! #f #t)" - exception:bad-variable + exception:bad-set! (eval '(set! #f #t) (interaction-environment))) (pass-if-exception "(set! #\\space #f)" - exception:bad-variable + exception:bad-set! (eval '(set! #\space #f) (interaction-environment))))) @@ -974,12 +966,12 @@ (with-test-prefix "missing or extra expression" (pass-if-exception "(quote)" - exception:missing/extra-expr + exception:bad-quote (eval '(quote) (interaction-environment))) (pass-if-exception "(quote a b)" - exception:missing/extra-expr + exception:bad-quote (eval '(quote a b) (interaction-environment))))) @@ -1010,46 +1002,27 @@ (do ((n 0 (1+ n))) ((> n 5)) (pass-if n - (let ((cond (make-iterations-cond n))) - (while (cond))) - #t))) + (eval `(letrec ((make-iterations-cond + (lambda (n) + (lambda () + (cond ((not n) + (error "oops, condition re-tested after giving false")) + ((= 0 n) + (set! n #f) + #f) + (else + (set! n (1- n)) + #t)))))) + (let ((cond (make-iterations-cond ,n))) + (while (cond)) + #t)) + (interaction-environment))))) (pass-if "initially false" (while #f (unreachable)) #t) - (with-test-prefix "in empty environment" - - ;; an environment with no bindings at all - (define empty-environment - (make-module 1)) - - ;; these tests are 'unresolved because to work with ice-9 syncase it was - ;; necessary to drop the unquote from `do' in the implementation, and - ;; unfortunately that makes `while' depend on its evaluation environment - - (pass-if "empty body" - (throw 'unresolved) - (eval `(,while #f) - empty-environment) - #t) - - (pass-if "initially false" - (throw 'unresolved) - (eval `(,while #f - #f) - empty-environment) - #t) - - (pass-if "iterating" - (throw 'unresolved) - (let ((cond (make-iterations-cond 3))) - (eval `(,while (,cond) - 123 456) - empty-environment)) - #t)) - (with-test-prefix "iterations" (do ((n 0 (1+ n))) ((> n 5)) @@ -1063,8 +1036,9 @@ (with-test-prefix "break" (pass-if-exception "too many args" exception:wrong-num-args - (while #t - (break 1))) + (eval '(while #t + (break 1)) + (interaction-environment))) (with-test-prefix "from cond" (pass-if "first" @@ -1135,8 +1109,9 @@ (with-test-prefix "continue" (pass-if-exception "too many args" exception:wrong-num-args - (while #t - (continue 1))) + (eval '(while #t + (continue 1)) + (interaction-environment))) (with-test-prefix "from cond" (do ((n 0 (1+ n))) diff --git a/test-suite/tests/threads.test b/test-suite/tests/threads.test index caace7fd4..26efe8580 100644 --- a/test-suite/tests/threads.test +++ b/test-suite/tests/threads.test @@ -2,25 +2,38 @@ ;;;; ;;;; Copyright 2003, 2006, 2007 Free Software Foundation, Inc. ;;;; -;;;; 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 2, or (at your option) -;;;; any later version. -;;;; -;;;; This program is distributed in the hope that it will be useful, +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;;; GNU General Public License for more details. -;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this software; see the file COPYING. If not, write to -;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;;; Boston, MA 02110-1301 USA +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (define-module (test-threads) :use-module (ice-9 threads) :use-module (test-suite lib)) +(define (asyncs-still-working?) + (let ((a #f)) + (system-async-mark (lambda () + (set! a #t))) + ;; The point of the following (equal? ...) is to go through + ;; primitive code (scm_equal_p) that includes a SCM_TICK call and + ;; hence gives system asyncs a chance to run. Of course the + ;; evaluator (eval.i.c) also calls SCM_TICK regularly, but in the + ;; near future we may be using the VM instead of the traditional + ;; compiler, and then we will still want asyncs-still-working? to + ;; work. (The VM should probably have SCM_TICK calls too, but + ;; let's not rely on that here.) + (equal? '(a b c) '(a b c)) + a)) (if (provided? 'threads) (begin @@ -101,6 +114,9 @@ (with-test-prefix "n-for-each-par-map" + (pass-if "asyncs are still working 2" + (asyncs-still-working?)) + (pass-if "0 in limit 10" (n-for-each-par-map 10 noop noop '()) #t) @@ -143,12 +159,18 @@ (with-test-prefix "lock-mutex" + (pass-if "asyncs are still working 3" + (asyncs-still-working?)) + (pass-if "timed locking fails if timeout exceeded" (let ((m (make-mutex))) (lock-mutex m) (let ((t (begin-thread (lock-mutex m (+ (current-time) 1))))) (not (join-thread t))))) + (pass-if "asyncs are still working 6" + (asyncs-still-working?)) + (pass-if "timed locking succeeds if mutex unlocked within timeout" (let* ((m (make-mutex)) (c (make-condition-variable)) @@ -164,7 +186,12 @@ (unlock-mutex cm) (sleep 1) (unlock-mutex m) - (join-thread t))))) + (join-thread t)))) + + (pass-if "asyncs are still working 7" + (asyncs-still-working?)) + + ) ;; ;; timed mutex unlocking @@ -172,12 +199,18 @@ (with-test-prefix "unlock-mutex" + (pass-if "asyncs are still working 5" + (asyncs-still-working?)) + (pass-if "timed unlocking returns #f if timeout exceeded" (let ((m (make-mutex)) (c (make-condition-variable))) (lock-mutex m) (not (unlock-mutex m c (current-time))))) + (pass-if "asyncs are still working 4" + (asyncs-still-working?)) + (pass-if "timed unlocking returns #t if condition signaled" (let ((m1 (make-mutex)) (m2 (make-mutex)) @@ -226,7 +259,36 @@ (pass-if "timed joining succeeds if thread exits within timeout" (let ((t (begin-thread (begin (sleep 1) #t)))) - (join-thread t (+ (current-time) 2))))) + (join-thread t (+ (current-time) 2)))) + + (pass-if "asyncs are still working 1" + (asyncs-still-working?)) + + ;; scm_join_thread_timed has a SCM_TICK in the middle of it, + ;; to allow asyncs to run (including signal delivery). We + ;; used to have a bug whereby if the joined thread terminated + ;; at the same time as the joining thread is in this SCM_TICK, + ;; scm_join_thread_timed would not notice and would hang + ;; forever. So in this test we are setting up the following + ;; sequence of events. + ;; T=0 other thread is created and starts running + ;; T=2 main thread sets up an async that will sleep for 10 seconds + ;; T=2 main thread calls join-thread, which will... + ;; T=2 ...call the async, which starts sleeping + ;; T=5 other thread finishes its work and terminates + ;; T=7 async completes, main thread continues inside join-thread. + (pass-if "don't hang when joined thread terminates in SCM_TICK" + (let ((other-thread (make-thread sleep 5))) + (letrec ((delay-count 10) + (aproc (lambda () + (set! delay-count (- delay-count 1)) + (if (zero? delay-count) + (sleep 5) + (system-async-mark aproc))))) + (sleep 2) + (system-async-mark aproc) + (join-thread other-thread))) + #t)) ;; ;; thread cancellation diff --git a/test-suite/tests/time.test b/test-suite/tests/time.test index d5639eb68..38a49d384 100644 --- a/test-suite/tests/time.test +++ b/test-suite/tests/time.test @@ -3,20 +3,19 @@ ;;;; ;;;; Copyright (C) 1999, 2004, 2006, 2007, 2008 Free Software Foundation, Inc. ;;;; -;;;; 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 2, or (at your option) -;;;; any later version. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. ;;;; -;;;; This program is distributed in the hope that it will be useful, +;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;;; GNU General Public License for more details. +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. ;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this software; see the file COPYING. If not, write to -;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;;; Boston, MA 02110-1301 USA +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (define-module (test-suite test-time) #:use-module (test-suite lib) diff --git a/test-suite/tests/tree-il.test b/test-suite/tests/tree-il.test new file mode 100644 index 000000000..73ea9c1a7 --- /dev/null +++ b/test-suite/tests/tree-il.test @@ -0,0 +1,591 @@ +;;;; tree-il.test --- test suite for compiling tree-il -*- scheme -*- +;;;; Andy Wingo --- May 2009 +;;;; +;;;; Copyright (C) 2009 Free Software Foundation, Inc. +;;;; +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. +;;;; +;;;; This library is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +(define-module (test-suite tree-il) + #:use-module (test-suite lib) + #:use-module (system base compile) + #:use-module (system base pmatch) + #:use-module (system base message) + #:use-module (language tree-il) + #:use-module (language glil) + #:use-module (srfi srfi-13)) + +;; Of course, the GLIL that is emitted depends on the source info of the +;; input. Here we're not concerned about that, so we strip source +;; information from the incoming tree-il. + +(define (strip-source x) + (post-order! (lambda (x) (set! (tree-il-src x) #f)) + x)) + +(define-syntax assert-scheme->glil + (syntax-rules () + ((_ in out) + (let ((tree-il (strip-source + (compile 'in #:from 'scheme #:to 'tree-il)))) + (pass-if 'in + (equal? (unparse-glil (compile tree-il #:from 'tree-il #:to 'glil)) + 'out)))))) + +(define-syntax assert-tree-il->glil + (syntax-rules () + ((_ in out) + (pass-if 'in + (let ((tree-il (strip-source (parse-tree-il 'in)))) + (equal? (unparse-glil (compile tree-il #:from 'tree-il #:to 'glil)) + 'out)))))) + +(define-syntax assert-tree-il->glil/pmatch + (syntax-rules () + ((_ in pat test ...) + (let ((exp 'in)) + (pass-if 'in + (let ((glil (unparse-glil + (compile (strip-source (parse-tree-il exp)) + #:from 'tree-il #:to 'glil)))) + (pmatch glil + (pat (guard test ...) #t) + (else #f)))))))) + +(with-test-prefix "void" + (assert-tree-il->glil + (void) + (program 0 0 0 () (void) (call return 1))) + (assert-tree-il->glil + (begin (void) (const 1)) + (program 0 0 0 () (const 1) (call return 1))) + (assert-tree-il->glil + (apply (primitive +) (void) (const 1)) + (program 0 0 0 () (void) (call add1 1) (call return 1)))) + +(with-test-prefix "application" + (assert-tree-il->glil + (apply (toplevel foo) (const 1)) + (program 0 0 0 () (toplevel ref foo) (const 1) (call goto/args 1))) + (assert-tree-il->glil/pmatch + (begin (apply (toplevel foo) (const 1)) (void)) + (program 0 0 0 () (toplevel ref foo) (const 1) (mv-call 1 ,l1) + (call drop 1) (branch br ,l2) + (label ,l3) (mv-bind () #f) (unbind) + (label ,l4) + (void) (call return 1)) + (and (eq? l1 l3) (eq? l2 l4))) + (assert-tree-il->glil + (apply (toplevel foo) (apply (toplevel bar))) + (program 0 0 0 () (toplevel ref foo) (toplevel ref bar) (call call 0) + (call goto/args 1)))) + +(with-test-prefix "conditional" + (assert-tree-il->glil/pmatch + (if (const #t) (const 1) (const 2)) + (program 0 0 0 () (const #t) (branch br-if-not ,l1) + (const 1) (call return 1) + (label ,l2) (const 2) (call return 1)) + (eq? l1 l2)) + + (assert-tree-il->glil/pmatch + (begin (if (const #t) (const 1) (const 2)) (const #f)) + (program 0 0 0 () (const #t) (branch br-if-not ,l1) (branch br ,l2) + (label ,l3) (label ,l4) (const #f) (call return 1)) + (eq? l1 l3) (eq? l2 l4)) + + (assert-tree-il->glil/pmatch + (apply (primitive null?) (if (const #t) (const 1) (const 2))) + (program 0 0 0 () (const #t) (branch br-if-not ,l1) + (const 1) (branch br ,l2) + (label ,l3) (const 2) (label ,l4) + (call null? 1) (call return 1)) + (eq? l1 l3) (eq? l2 l4))) + +(with-test-prefix "primitive-ref" + (assert-tree-il->glil + (primitive +) + (program 0 0 0 () (toplevel ref +) (call return 1))) + + (assert-tree-il->glil + (begin (primitive +) (const #f)) + (program 0 0 0 () (const #f) (call return 1))) + + (assert-tree-il->glil + (apply (primitive null?) (primitive +)) + (program 0 0 0 () (toplevel ref +) (call null? 1) + (call return 1)))) + +(with-test-prefix "lexical refs" + (assert-tree-il->glil + (let (x) (y) ((const 1)) (lexical x y)) + (program 0 0 1 () + (const 1) (bind (x #f 0)) (lexical #t #f set 0) + (lexical #t #f ref 0) (call return 1) + (unbind))) + + (assert-tree-il->glil + (let (x) (y) ((const 1)) (begin (lexical x y) (const #f))) + (program 0 0 1 () + (const 1) (bind (x #f 0)) (lexical #t #f set 0) + (const #f) (call return 1) + (unbind))) + + (assert-tree-il->glil + (let (x) (y) ((const 1)) (apply (primitive null?) (lexical x y))) + (program 0 0 1 () + (const 1) (bind (x #f 0)) (lexical #t #f set 0) + (lexical #t #f ref 0) (call null? 1) (call return 1) + (unbind)))) + +(with-test-prefix "lexical sets" + (assert-tree-il->glil + ;; unreferenced sets may be optimized away -- make sure they are ref'd + (let (x) (y) ((const 1)) + (set! (lexical x y) (apply (primitive 1+) (lexical x y)))) + (program 0 0 1 () + (const 1) (bind (x #t 0)) (lexical #t #t box 0) + (lexical #t #t ref 0) (call add1 1) (lexical #t #t set 0) + (void) (call return 1) + (unbind))) + + (assert-tree-il->glil + (let (x) (y) ((const 1)) + (begin (set! (lexical x y) (apply (primitive 1+) (lexical x y))) + (lexical x y))) + (program 0 0 1 () + (const 1) (bind (x #t 0)) (lexical #t #t box 0) + (lexical #t #t ref 0) (call add1 1) (lexical #t #t set 0) + (lexical #t #t ref 0) (call return 1) + (unbind))) + + (assert-tree-il->glil + (let (x) (y) ((const 1)) + (apply (primitive null?) + (set! (lexical x y) (apply (primitive 1+) (lexical x y))))) + (program 0 0 1 () + (const 1) (bind (x #t 0)) (lexical #t #t box 0) + (lexical #t #t ref 0) (call add1 1) (lexical #t #t set 0) (void) + (call null? 1) (call return 1) + (unbind)))) + +(with-test-prefix "module refs" + (assert-tree-il->glil + (@ (foo) bar) + (program 0 0 0 () + (module public ref (foo) bar) + (call return 1))) + + (assert-tree-il->glil + (begin (@ (foo) bar) (const #f)) + (program 0 0 0 () + (module public ref (foo) bar) (call drop 1) + (const #f) (call return 1))) + + (assert-tree-il->glil + (apply (primitive null?) (@ (foo) bar)) + (program 0 0 0 () + (module public ref (foo) bar) + (call null? 1) (call return 1))) + + (assert-tree-il->glil + (@@ (foo) bar) + (program 0 0 0 () + (module private ref (foo) bar) + (call return 1))) + + (assert-tree-il->glil + (begin (@@ (foo) bar) (const #f)) + (program 0 0 0 () + (module private ref (foo) bar) (call drop 1) + (const #f) (call return 1))) + + (assert-tree-il->glil + (apply (primitive null?) (@@ (foo) bar)) + (program 0 0 0 () + (module private ref (foo) bar) + (call null? 1) (call return 1)))) + +(with-test-prefix "module sets" + (assert-tree-il->glil + (set! (@ (foo) bar) (const 2)) + (program 0 0 0 () + (const 2) (module public set (foo) bar) + (void) (call return 1))) + + (assert-tree-il->glil + (begin (set! (@ (foo) bar) (const 2)) (const #f)) + (program 0 0 0 () + (const 2) (module public set (foo) bar) + (const #f) (call return 1))) + + (assert-tree-il->glil + (apply (primitive null?) (set! (@ (foo) bar) (const 2))) + (program 0 0 0 () + (const 2) (module public set (foo) bar) + (void) (call null? 1) (call return 1))) + + (assert-tree-il->glil + (set! (@@ (foo) bar) (const 2)) + (program 0 0 0 () + (const 2) (module private set (foo) bar) + (void) (call return 1))) + + (assert-tree-il->glil + (begin (set! (@@ (foo) bar) (const 2)) (const #f)) + (program 0 0 0 () + (const 2) (module private set (foo) bar) + (const #f) (call return 1))) + + (assert-tree-il->glil + (apply (primitive null?) (set! (@@ (foo) bar) (const 2))) + (program 0 0 0 () + (const 2) (module private set (foo) bar) + (void) (call null? 1) (call return 1)))) + +(with-test-prefix "toplevel refs" + (assert-tree-il->glil + (toplevel bar) + (program 0 0 0 () + (toplevel ref bar) + (call return 1))) + + (assert-tree-il->glil + (begin (toplevel bar) (const #f)) + (program 0 0 0 () + (toplevel ref bar) (call drop 1) + (const #f) (call return 1))) + + (assert-tree-il->glil + (apply (primitive null?) (toplevel bar)) + (program 0 0 0 () + (toplevel ref bar) + (call null? 1) (call return 1)))) + +(with-test-prefix "toplevel sets" + (assert-tree-il->glil + (set! (toplevel bar) (const 2)) + (program 0 0 0 () + (const 2) (toplevel set bar) + (void) (call return 1))) + + (assert-tree-il->glil + (begin (set! (toplevel bar) (const 2)) (const #f)) + (program 0 0 0 () + (const 2) (toplevel set bar) + (const #f) (call return 1))) + + (assert-tree-il->glil + (apply (primitive null?) (set! (toplevel bar) (const 2))) + (program 0 0 0 () + (const 2) (toplevel set bar) + (void) (call null? 1) (call return 1)))) + +(with-test-prefix "toplevel defines" + (assert-tree-il->glil + (define bar (const 2)) + (program 0 0 0 () + (const 2) (toplevel define bar) + (void) (call return 1))) + + (assert-tree-il->glil + (begin (define bar (const 2)) (const #f)) + (program 0 0 0 () + (const 2) (toplevel define bar) + (const #f) (call return 1))) + + (assert-tree-il->glil + (apply (primitive null?) (define bar (const 2))) + (program 0 0 0 () + (const 2) (toplevel define bar) + (void) (call null? 1) (call return 1)))) + +(with-test-prefix "constants" + (assert-tree-il->glil + (const 2) + (program 0 0 0 () + (const 2) (call return 1))) + + (assert-tree-il->glil + (begin (const 2) (const #f)) + (program 0 0 0 () + (const #f) (call return 1))) + + (assert-tree-il->glil + (apply (primitive null?) (const 2)) + (program 0 0 0 () + (const 2) (call null? 1) (call return 1)))) + +(with-test-prefix "lambda" + (assert-tree-il->glil + (lambda (x) (y) () (const 2)) + (program 0 0 0 () + (program 1 0 0 () + (bind (x #f 0)) + (const 2) (call return 1)) + (call return 1))) + + (assert-tree-il->glil + (lambda (x x1) (y y1) () (const 2)) + (program 0 0 0 () + (program 2 0 0 () + (bind (x #f 0) (x1 #f 1)) + (const 2) (call return 1)) + (call return 1))) + + (assert-tree-il->glil + (lambda x y () (const 2)) + (program 0 0 0 () + (program 1 1 0 () + (bind (x #f 0)) + (const 2) (call return 1)) + (call return 1))) + + (assert-tree-il->glil + (lambda (x . x1) (y . y1) () (const 2)) + (program 0 0 0 () + (program 2 1 0 () + (bind (x #f 0) (x1 #f 1)) + (const 2) (call return 1)) + (call return 1))) + + (assert-tree-il->glil + (lambda (x . x1) (y . y1) () (lexical x y)) + (program 0 0 0 () + (program 2 1 0 () + (bind (x #f 0) (x1 #f 1)) + (lexical #t #f ref 0) (call return 1)) + (call return 1))) + + (assert-tree-il->glil + (lambda (x . x1) (y . y1) () (lexical x1 y1)) + (program 0 0 0 () + (program 2 1 0 () + (bind (x #f 0) (x1 #f 1)) + (lexical #t #f ref 1) (call return 1)) + (call return 1))) + + (assert-tree-il->glil + (lambda (x) (x1) () (lambda (y) (y1) () (lexical x x1))) + (program 0 0 0 () + (program 1 0 0 () + (bind (x #f 0)) + (program 1 0 0 () + (bind (y #f 0)) + (lexical #f #f ref 0) (call return 1)) + (lexical #t #f ref 0) + (call vector 1) + (call make-closure 2) + (call return 1)) + (call return 1)))) + +(with-test-prefix "sequence" + (assert-tree-il->glil + (begin (begin (const 2) (const #f)) (const #t)) + (program 0 0 0 () + (const #t) (call return 1))) + + (assert-tree-il->glil + (apply (primitive null?) (begin (const #f) (const 2))) + (program 0 0 0 () + (const 2) (call null? 1) (call return 1)))) + +;; FIXME: binding info for or-hacked locals might bork the disassembler, +;; and could be tightened in any case +(with-test-prefix "the or hack" + (assert-tree-il->glil/pmatch + (let (x) (y) ((const 1)) + (if (lexical x y) + (lexical x y) + (let (a) (b) ((const 2)) + (lexical a b)))) + (program 0 0 1 () + (const 1) (bind (x #f 0)) (lexical #t #f set 0) + (lexical #t #f ref 0) (branch br-if-not ,l1) + (lexical #t #f ref 0) (call return 1) + (label ,l2) + (const 2) (bind (a #f 0)) (lexical #t #f set 0) + (lexical #t #f ref 0) (call return 1) + (unbind) + (unbind)) + (eq? l1 l2)) + + ;; second bound var is unreferenced + (assert-tree-il->glil/pmatch + (let (x) (y) ((const 1)) + (if (lexical x y) + (lexical x y) + (let (a) (b) ((const 2)) + (lexical x y)))) + (program 0 0 1 () + (const 1) (bind (x #f 0)) (lexical #t #f set 0) + (lexical #t #f ref 0) (branch br-if-not ,l1) + (lexical #t #f ref 0) (call return 1) + (label ,l2) + (lexical #t #f ref 0) (call return 1) + (unbind)) + (eq? l1 l2))) + +(with-test-prefix "apply" + (assert-tree-il->glil + (apply (primitive @apply) (toplevel foo) (toplevel bar)) + (program 0 0 0 () (toplevel ref foo) (toplevel ref bar) (call goto/apply 2))) + (assert-tree-il->glil/pmatch + (begin (apply (primitive @apply) (toplevel foo) (toplevel bar)) (void)) + (program 0 0 0 () + (toplevel ref apply) (toplevel ref foo) (toplevel ref bar) (mv-call 2 ,l1) + (call drop 1) (branch br ,l2) (label ,l3) (mv-bind () #f) (unbind) + (label ,l4) + (void) (call return 1)) + (and (eq? l1 l3) (eq? l2 l4))) + (assert-tree-il->glil + (apply (toplevel foo) (apply (toplevel @apply) (toplevel bar) (toplevel baz))) + (program 0 0 0 () + (toplevel ref foo) + (toplevel ref bar) (toplevel ref baz) (call apply 2) + (call goto/args 1)))) + +(with-test-prefix "call/cc" + (assert-tree-il->glil + (apply (primitive @call-with-current-continuation) (toplevel foo)) + (program 0 0 0 () (toplevel ref foo) (call goto/cc 1))) + (assert-tree-il->glil/pmatch + (begin (apply (primitive @call-with-current-continuation) (toplevel foo)) (void)) + (program 0 0 0 () + (toplevel ref call-with-current-continuation) (toplevel ref foo) (mv-call 1 ,l1) + (call drop 1) (branch br ,l2) (label ,l3) (mv-bind () #f) (unbind) + (label ,l4) + (void) (call return 1)) + (and (eq? l1 l3) (eq? l2 l4))) + (assert-tree-il->glil + (apply (toplevel foo) + (apply (toplevel @call-with-current-continuation) (toplevel bar))) + (program 0 0 0 () + (toplevel ref foo) + (toplevel ref bar) (call call/cc 1) + (call goto/args 1)))) + + +(with-test-prefix "tree-il-fold" + + (pass-if "empty tree" + (let ((leaf? #f) (up? #f) (down? #f) (mark (list 'mark))) + (and (eq? mark + (tree-il-fold (lambda (x y) (set! leaf? #t) y) + (lambda (x y) (set! down? #t) y) + (lambda (x y) (set! up? #t) y) + mark + '())) + (not leaf?) + (not up?) + (not down?)))) + + (pass-if "lambda and application" + (let* ((leaves '()) (ups '()) (downs '()) + (result (tree-il-fold (lambda (x y) + (set! leaves (cons x leaves)) + (1+ y)) + (lambda (x y) + (set! downs (cons x downs)) + (1+ y)) + (lambda (x y) + (set! ups (cons x ups)) + (1+ y)) + 0 + (parse-tree-il + '(lambda (x y) (x1 y1) + (apply (toplevel +) + (lexical x x1) + (lexical y y1))))))) + (and (equal? (map strip-source leaves) + (list (make-lexical-ref #f 'y 'y1) + (make-lexical-ref #f 'x 'x1) + (make-toplevel-ref #f '+))) + (= (length downs) 2) + (equal? (reverse (map strip-source ups)) + (map strip-source downs)))))) + + +;;; +;;; Warnings. +;;; + +;; Make sure we get English messages. +(setlocale LC_ALL "C") + +(define (call-with-warnings thunk) + (let ((port (open-output-string))) + (with-fluid* *current-warning-port* port + thunk) + (let ((warnings (get-output-string port))) + (string-tokenize warnings + (char-set-complement (char-set #\newline)))))) + +(define %opts-w-unused + '(#:warnings (unused-variable))) + + +(with-test-prefix "warnings" + + (pass-if "unknown warning type" + (let ((w (call-with-warnings + (lambda () + (compile #t #:opts '(#:warnings (does-not-exist))))))) + (and (= (length w) 1) + (number? (string-contains (car w) "unknown warning"))))) + + (with-test-prefix "unused-variable" + + (pass-if "quiet" + (null? (call-with-warnings + (lambda () + (compile '(lambda (x y) (+ x y)) + #:opts %opts-w-unused))))) + + (pass-if "let/unused" + (let ((w (call-with-warnings + (lambda () + (compile '(lambda (x) + (let ((y (+ x 2))) + x)) + #:opts %opts-w-unused))))) + (and (= (length w) 1) + (number? (string-contains (car w) "unused variable `y'"))))) + + (pass-if "shadowed variable" + (let ((w (call-with-warnings + (lambda () + (compile '(lambda (x) + (let ((y x)) + (let ((y (+ x 2))) + (+ x y)))) + #:opts %opts-w-unused))))) + (and (= (length w) 1) + (number? (string-contains (car w) "unused variable `y'"))))) + + (pass-if "letrec" + (null? (call-with-warnings + (lambda () + (compile '(lambda () + (letrec ((x (lambda () (y))) + (y (lambda () (x)))) + y)) + #:opts %opts-w-unused))))) + + (pass-if "unused argument" + ;; Unused arguments should not be reported. + (null? (call-with-warnings + (lambda () + (compile '(lambda (x y z) #t) + #:opts %opts-w-unused))))))) diff --git a/test-suite/tests/unif.test b/test-suite/tests/unif.test index 576a9286c..61dbeb89e 100644 --- a/test-suite/tests/unif.test +++ b/test-suite/tests/unif.test @@ -5,7 +5,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/test-suite/tests/vectors.test b/test-suite/tests/vectors.test index 738a0828a..22434bfc6 100644 --- a/test-suite/tests/vectors.test +++ b/test-suite/tests/vectors.test @@ -2,20 +2,19 @@ ;;;; ;;;; Copyright (C) 2003, 2006 Free Software Foundation, Inc. ;;;; -;;;; 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 2, or (at your option) -;;;; any later version. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. ;;;; -;;;; This program is distributed in the hope that it will be useful, +;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;;; GNU General Public License for more details. +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. ;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this software; see the file COPYING. If not, write to -;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;;; Boston, MA 02110-1301 USA +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (define-module (test-suite vectors) :use-module (test-suite lib)) diff --git a/test-suite/tests/version.test b/test-suite/tests/version.test index b2a491950..5b7acc93d 100644 --- a/test-suite/tests/version.test +++ b/test-suite/tests/version.test @@ -3,20 +3,19 @@ ;;;; ;;;; Copyright (C) 2000, 2001, 2006 Free Software Foundation, Inc. ;;;; -;;;; 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 2, or (at your option) -;;;; any later version. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. ;;;; -;;;; This program is distributed in the hope that it will be useful, +;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;;; GNU General Public License for more details. +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. ;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this software; see the file COPYING. If not, write to -;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;;; Boston, MA 02110-1301 USA +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (use-modules (test-suite lib)) diff --git a/test-suite/tests/weaks.test b/test-suite/tests/weaks.test index 7bb77b07c..b469887c2 100644 --- a/test-suite/tests/weaks.test +++ b/test-suite/tests/weaks.test @@ -4,7 +4,7 @@ ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either -;;;; version 2.1 of the License, or (at your option) any later version. +;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/testsuite/Makefile.am b/testsuite/Makefile.am index 3c7ed7341..2bc78142c 100644 --- a/testsuite/Makefile.am +++ b/testsuite/Makefile.am @@ -1,8 +1,8 @@ TESTS_ENVIRONMENT = \ - $(top_builddir)/pre-inst-guile \ + $(top_builddir)/meta/guile \ -l $(srcdir)/run-vm-tests.scm -e run-vm-tests -check_SCRIPTS = \ +TESTS = \ t-basic-contructs.scm \ t-global-bindings.scm \ t-catch.scm \ @@ -24,6 +24,4 @@ check_SCRIPTS = \ t-match.scm \ t-mutual-toplevel-defines.scm -TESTS = $(check_SCRIPTS) - -EXTRA_DIST = run-vm-tests.scm +EXTRA_DIST = run-vm-tests.scm $(TESTS) diff --git a/testsuite/run-vm-tests.scm b/testsuite/run-vm-tests.scm index 1485fc1e6..f7eba40bb 100644 --- a/testsuite/run-vm-tests.scm +++ b/testsuite/run-vm-tests.scm @@ -1,19 +1,18 @@ ;;; run-vm-tests.scm -- Run Guile-VM's test suite. ;;; -;;; Copyright 2005 Ludovic Courtès +;;; Copyright 2005, 2009 Free Software Foundation, Inc. ;;; -;;; -;;; 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 2 of the License, or -;;; (at your option) any later version. +;;; This program is free software; you can redistribute it and/or +;;; modify it under the terms of the GNU Lesser General Public License +;;; as published by the Free Software Foundation; either version 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. +;;; GNU Lesser General Public License for more details. ;;; -;;; You should have received a copy of the GNU General Public License +;;; You should have received a copy of the GNU Lesser General Public License ;;; along with this program; if not, write to the Free Software ;;; Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA @@ -85,9 +84,7 @@ equal in the sense of @var{equal?}." (failed (length (filter not res)))) (if (= 0 failed) - (begin - (format #t "~%All ~a tests passed~%" total) - (exit 0)) + (exit 0) (begin (format #t "~%~a tests failed out of ~a~%" failed total) diff --git a/testsuite/t-match.scm b/testsuite/t-match.scm index 4b85f30d3..ed56ae7ef 100644 --- a/testsuite/t-match.scm +++ b/testsuite/t-match.scm @@ -12,7 +12,7 @@ (define (matches? obj) ; (format #t "matches? ~a~%" obj) (match obj - (($ stuff) => #t) + (($ stuff) #t) ; (blurps #t) ("hello" #t) (else #f)))